1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
#+title: Namespaced Extensions Only ActivityStreams
#+author: Vivien Kraus
#+email: vivien@planete-kraus.eu
#+language: en
* Namespaced Extensions Only ActivityStreams
ActivityStreams is cool, but json-ld is horribly complex. We believe
that it’s OK to define the NEO-ActivityStreams format by only
accepting JSON-LD that:
- have exactly one top-level object;
- have exactly one context object;
- the context object is directly in the top-level object, at the top
of the file;
- the context is an array, a single string, or a single map;
- if an array, the first elements of the array is a list of guaranteed
non-overlapping context URIs, that do not change the meaning of the
definitions of other contexts, and that dereference to constant
definitions;
- the last element of the array is optionally a map from prefixes to
namespaces (strings ending in '#' or '/');
- there are no two overlapping namespaced extensions.
It is OK to expect context URIs to be immutable in all cases, because
parsing a json-ld document should yield the exact same semantics
whenever it is parsed: whether the server hosting the context is
offline, or whether its domain named has been reclaimed by a malicious
entity, for instance. If the semantics of the context change in a
backward-incompatible way, the easy solution for the context author is
to version the context document and host it in a version-dependent
URI.
We believe that it is OK to have all these constraints because it
means server functionality can be achieved just by looking at the
pre-parsed context URIs, and client-specific extensions can be put
under a namespace.
Client-specific extensions should NOT add any term definition in the
context. This is not idiomatic json, and is not very readable (URI
values for properties would be represented as a map with to keys,
'@value' and '@type' mapped to "@id"), however we believe noone
actually reads json-ld data, and this makes server-side processing way
easier.
** Server-side processing of NEO-AS
Servers process the activities according to a set of semantic rules
for the data, expressed by context URIs. If an activity uses an
unknown context URI, the server assumes that it does not interfere
with the contexts it recognizes and processes the data without needing
to understand those it does not recognize. Therefore, the server never
has to fetch any context from the web. When transmitting a NEO-AS
object, the server should re-write the non-namespaced properties and
discard context URIs that it does not understand. It should also make
sure that no two namespaces use the same prefix, and transmit all the
namespaced data. This way, downstream users of the object can parse it
as full JSON-LD.
** Client-side processing of NEO-AS
Client-side extension data should be generated under a prefix that is
not already bound in the existing data. Parsing the data should be a
2-step procedure: first, scan the context to find which prefix is
bound to the extension namespace, and then use this prefix to
dereference the object properties. Since the context object is at the
top, parsing extension data is done in one step.
** Examples
Here are two examples of how to convert json-ld data from the json-ld
playground to neo-as. Many of the examples use the schema.org context,
without a namespace.
*** Person
Here is how the Person example can put the schema.org vocabulary under
a proper namespace, in case it is expected to not be immutable.
The source JSON-LD:
#+begin_src js :eval no
{
"@context": "http://schema.org/",
"@type": "Person",
"name": "Jane Doe",
"jobTitle": "Professor",
"telephone": "(425) 123-4567",
"url": "http://www.janedoe.com"
}
#+end_src
is now converted to:
#+begin_src js :eval no
{
"@context": { "schema": "http://schema.org/" },
"@type": "Person",
"schema:name": "Jane Doe",
"schema:jobTitle": "Professor",
"schema:telephone": "(425) 123-4567",
"schema:url": { "@value": "http://www.janedoe.com", "@type": "@id" }
}
#+end_src
Note that the =schema:url= value starts with =http://=, so it would be
OK to not decorate it with =@value= and =@type: @id=.
*** Event
This example adds a term definition in the context, which we do not
want.
#+begin_src js :eval no
{
"@context": {
"ical": "http://www.w3.org/2002/12/cal/ical#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ical:dtstart": {
"@type": "xsd:dateTime"
}
},
"ical:summary": "Lady Gaga Concert",
"ical:location": "New Orleans Arena, New Orleans, Louisiana, USA",
"ical:dtstart": "2011-04-09T20:00:00Z"
}
#+end_src
It is converted to:
#+begin_src js :eval no
{
"@context": {
"ical": "http://www.w3.org/2002/12/cal/ical#",
"xsd": "http://www.w3.org/2001/XMLSchema#"
},
"ical:summary": "Lady Gaga Concert",
"ical:location": "New Orleans Arena, New Orleans, Louisiana, USA",
"ical:dtstart": { "@value": "2011-04-09T20:00:00Z", "@type": "xsd:dateTime" }
}
#+end_src
# Local Variables:
# mode: org
# End:
|