summaryrefslogtreecommitdiff
path: root/README
blob: f5156dcf61b51bf64f9cf52f1ee676b703916e66 (plain)
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: