forked from shapetrees/specification
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprimer.bs
305 lines (247 loc) · 17 KB
/
primer.bs
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
<pre class="metadata">
Title: Shape Trees Primer
Shortname: shapetrees-primer
Level: 1
Max ToC Depth: 2
Status: w3c/ED
Group: w3c
URL: https://shapetrees.org/primer
Editor: Eric Prud'hommeaux
Editor: Justin Bingham
Editor: Josh Collins
Markup Shorthands: markdown yes
Abstract:
This primer introduces shape trees and describes how Semantic Web Applications use them to consistently interoperate over constellations of data structures organized in resource hierarchies used by protocols such as LDP and Solid.
</pre>
<!-- For bikeshed style overrides -->
<style>
code.container {
color: #005555;
}
code.notes {
color: #770033;
}
code.citation {
color: #330077;
}
code.image {
color: #337700;
}
</style>
Introduction {#introduction}
=====================
Realizing the value proposition of the Semantic Web lies in building useful and robust applications that can interoperate over linked data.
Protocols such as [[LDP]] and Solid organize linked data graphs into resource hierarchies, providing a foundation upon which these robust and interoperable applications can be created.
Application interoperability depends on applications sharing semantics for relationships and data structures. Existing technologies fulfill portions of those dependencies:
* RDF's foundation in unambiguous identifiers provides an infrastructure that allows for interoperability, but does not specifically encouraging or enforce it.
* Shape languages (e.g. ShEx and [[SHACL]]) provide machine-readable, enforceable data structure definitions on single resources.
For applications that operate on more interconnected resources, *Shape Trees* express the layout of those resources and associate them with their respective shapes.
Shape trees marry RDF vocabularies, shapes, and resources into "little trees" that provide machine to machine interoperability,
while at the same time creating concepts that humans can easily comprehend, such as medical records, notes, notebooks,
calendars, and financial records.
This allows one to treat a set of related resources as a single grouping, and apply that to a range of operations including access control,
data organization, data validation, and data migration.
Shape trees are defined as an RDF graph structure that expresses a set of expected behaviors by agents that work with them.
These semantics can be implemented by a server or a client-side library that proxies requests to a server.
Shape Tree Structure {#structure}
=====================
The following image introduces Shape trees by way of an example shape tree for interoperable notes called "CommonNote".
It captures notes, any images included therein, as well as the note's citations.
The example image includes three columns:
* Shape definitions (expressed in ShEx) for the resources described by the CommonNote shape tree
* A shape tree (expressed in Turtle) for CommonNote
* Example data instances adhering to the CommonNote ShapeTree (a "resource hierarchy")
<table width="100%" align="center">
<thead>
<tr>
<th width="31%" align="center"><u>Shapes (ShEx)</u></th>
<th width="42%" align="center"><u>Shape Tree (Turtle)</u></th>
<th width="27%" align="center"><u>Resource Hierarchy</u></th>
</tr>
</thead>
</table>
<img src="shape-tree.svg" width="100%" alt="colored example of ShEx schema, shape tree, and resource hierarchy" />
Here, <code class="container">/data/medicalNotes</code> and <code class="container">/data/astronomy/notes</code> are both shape tree instances of the <code class="container"><#container></code> shape tree.
They are both Containers per <code class="container"><#container> tree:expectsType tree:ShapeTreeContainer</code> and could contain any number of note shape tree instances per <code class="container">tree:contains <#note></code>.
In this example, <code class="notes">xrays-2019-08</code>, <code class="notes">GP-2020-04-18</code> and <code class="notes">blue-shift</code> respectively are shape tree instances of the <code class="notes"><#note></code> shape tree.
Each contains a binary <code class="image">image</code> and blue-shift has a <code class="citation">citation</code>.
A shape tree document can contain multiple shape tree definitions. A given definition in a shape tree resource can be referenced and used on its own as a standalone shape tree, or as part of an interconnected hierarchy of shape trees.
The shape tree describing the <code class="citation">citation</code> has the subject node <code class="citation"><#citation></code>.
This shape tree asserts that associated resources (e.g. <code class="citation">cit-M33.ttl</code>) must:
* Be a Resource per <code class="citation"><#citation> tree:expectsType tree:ShapeTreeResource</code>
* Have a name matching a URI template (i.e. must start with "cit-") per <code class="citation"><#citation> tree:matchesUriTemplate "cit-{name}"</code>
* Conform to the shape <code class="citation"><CommonNote#Citation></code> per <code class="citation"><#citation> tree:validatedBy <CommonNote#Citation></code>
## Shape Tree Predicates ## {#structure-predicates}
A shape tree consists of:
* An <dfn>id</dfn>: an addressable label for this shape tree<br/>
As with all RDF structures, providing an id makes it possible to address this entity from outside the document.
* An <dfn>expectsType</dfn>: type of the associated resource: <code>tree:ShapeTreeContainer</code>, <code>tree:ShapeTreeResource</code> OR <code>tree:ShapeTreeNonRDFResource</code>.<br/>
The expectsType specifies whether the associated resources should be a container, a normal resource, or an non-RDF source. Shape tree implementations
will map these resource types to the appropriate constructs for the intended platform (i.e. in an LDP environment tree:ShapeTreeResource would map to ldp:Resource).
* either of:
* A <dfn>label</dfn>: label for a resource which will always be created;<br/>
This is used when resources with specific names will appear in the resource hierarchy.
* A <dfn>matchesUriTemplate</dfn>: pattern for a resource to be matched against a POSTed Slug: header or a resource name in a PUT/PATCH.<br/>
This is used to constrain resource creation based resource name patterns.
* A <dfn>validatedBy</dfn>: The RDF graph structure of any POSTed or PUT resource must conform to this shape;<br/>
This allows shape trees to ensure that the data in the resource hierarchy conforms to the expected schemas.</li>
* An optional <dfn>supports</dfn>: an IRI to another shape tree.<br/>
This captures a relationship where a shape tree is dependent on another for purposes of ancillary tasks like indexing. It is expected to describe resources which extend or another shape tree.
* An optional <dfn>contains</dfn>: a list of nested shape trees.<br/>
This captures the containership of a conforming resource hierarchy. In addition to containing other shape trees, this list may include
<code>tree:AllowNone</code>, <code>tree:AllowAll</code>, <code>tree:AllowContainers</code>, <code>tree:AllowResources</code>, <code>tree:AllowNonRDFSources</code> which described the intended behavior when a resource is created that does not adhere to any matching matchesUriTemplate predicates.
* An optional <dfn>references</dfn>: a list of referenced shape trees.<br/>
These provide advice that the data in resources described by this shape tree references another shape tree. This enables connectivity of shape trees
without requiring direct nesting/containment of those relationships.
Annotating all shape trees within a given resource is an optional <dfn>hasShapeTreeDecoratorIndex</dfn>: An IRI containing an index of SKOS graphs.
As detailed in <a href="#describing">Describing Shape Trees</a> below, SKOS provides an extensible means to describe a shape tree in human-readable terms. The <code>tree:hasShapeTreeDecoratorIndex</code> allows shape tree maintainers to provide a reference to SKOS graphs that accurately and reliably describe the shape tree as intended, which is important for authorization use cases.
Planting a Shape Tree {#planting}
=====================
The above example describes an instance at <code class="notes">/data/CommonNotes</code>.
This is an LDP Container which is constrained to contain only instances of <code><CommonNoteShapeTree#note></code>.
This container is described by the shape tree <code><CommonNoteShapeTree#container></code>:
<pre>
<code class="container">
<#container>
tree:expectsType tree:ShapeTreeContainer ;
tree:contains <#note> .
</code>
</pre>
In order to create this, an application like NeverNote would use a <b>plant</b> operation to create an instance of the <code class="container"><#container></code> shape tree.
This plant operation is a POST to the parent Container with one or more <code>rel="ShapeTree"</code> Link header .
The resulting LDP Container for CommonNotes is expected to be shared with other applications.
Below, we use the name "OtherNote" as an example of another application which can consume and process data conforming to the shapes referenced by the CommonNote shape tree.
<figure>
<figcaption>Plant operation</figcaption>
<pre highlight="http">
POST /data/
Slug: CommonNotes
Link: <http://www.w3.org/ns/ldp#Container>; rel="type"
Link: <<a href="https://github.com/shapetrees/specification/blob/master/solidApps/staticRoot/nevernote/NeverNoteShapeTree.jsonld">http://commonnote.example/CommonNoteShapeTree#container</a>>; rel="ShapeTree"
</pre>
</figure>
The response identifies a LDP Container for CommonNotes notes:
<figure>
<figcaption>Plant response</figcaption>
<pre highlight="http">
HTTP 201 CREATED
Location: http://pod.example/data/CommonNotes/
Content-type: text/turtle; charset=utf-8
Content-length: 396
</pre>
</figure>
Planting a shape tree results in a new LDP Container in the resource hierarchy.
Metadata associated with this container describes the planted shape tree that manages the contents of the container.
<figure>
<figcaption>Contents of http://pod.example/data/CommonNotes/ related metadata</figcaption>
<pre highlight="turtle">
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix tree: <http://www.w3.org/ns/shapetree#>.
@prefix dc: <http://purl.org/dc/terms/>.
@prefix dcterms: <http://purl.org/dc/terms/>.
<>
tree:hasShapeTreeLocator <#bc1b490a-537d-4749-b778-cd7d6da3ac56> .
<#bc1b490a-537d-4749-b778-cd7d6da3ac56>
tree:hasRootShapeTree <http://commonnote.example/CommonNoteShapeTree#container> ;
tree:hasShapeTree <http://commonnote.example/CommonNoteShapeTree#container> ;
tree:hasShapeTreeInstancePath "." ;
tree:hasShapeTreeInstanceRoot </data/CommonNotes/> .
</pre>
</figure>
Creating Data Instances {#data-instance}
=====================
Despite NeverNote having planted the LDP Container <code>/data/CommonNotes</code>, it could be another application, OtherNote, which first creates data there.
When POSTing to any managed container, there is expected to be a contains shape tree matching the new resource.
If the shape tree includes a validatedBy, the POST must include a Link: rel="focusNode" header to identify the node in the POSTed data that should conform to that shape.
<figure>
<figcaption>POSTing to a managed container</figcaption>
<pre highlight="turtle">
POST /data/CommonNotes/
Link: <#note1>; rel="focusNode"
PREFIX : <http://nevernote.example/ns#>
PREFIX ldp: <http://www.w3.org/ns/ldp#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
<#note1>
:title "Note1" ;
:content "Don't believe the hype!" ;
:updated "2020-01-01T12:34:00Z"^^xsd:dateTime ;
:tagNames ("tag1" "tag2") .
</pre>
</figure>
When an application POSTs to a Managed Container, the shape tree-aware agent handling the POST locates the appropriate shape tree that is contained,
via the <code>tree:contains</code> predicate, that matches its URI template.
Issue: Add explanation of explicit header to guide "contains"
* If the shape tree includes a <code>tree:validatedBy</code> predicate, the POST body is parsed and the focus node is tested for conformance.
* If the posted resource is invalid, it will return with a 422 Unprocessable Entity message.
* If no matching shape tree is found, the agent will use any present <code>tree:Allow*</code> IRIs to determine whether to allow the new resource.
* If the posted resource is valid, the typical LDP processing will create an entity whose contents include the POSTed body.
#matching-contained-shapetree
Describing Shape Trees {#describing}
=====================
To aid in the human-readability of shape trees, one or more SKOS graphs can be used to provide a textual representation of the structure.
Making use of the <code>tree:hasShapeTree</code> predicate, labels can be applied to specific Shape Trees using any language.
A SKOS index document allows for discovery of multiple definitions of a Shape Tree supporting multiple language preferences and cognitive abilities.
The convention on how this index of SKOS graphs is structured and used, along with the rules to govern the selection of the appropriate graph for a user is the responsibility of the ecosystem using Shape Trees.
<figure>
<figcaption>Sample SKOS index document, with references to English and Russian representations of the CommonNotes shape tree</figcaption>
<pre highlight="turtle">
<#index>
a tree:ShapeTreeDecoratorIndex ;
treeIndex:hasSeries <#en>, <#ru> .
<#en>
a tree:ShapeTreeDecoratorSeries ;
tree:hasHierarchy <#en-v1>, <#en-v1.1> .
<#en-v1>
a tree:ShapeTreeDecoratorHierarchy ;
xsd:lang "en" ;
tree:hasVersion "1.0" ;
tree:hasSkosGraph <https://commonnote.example/CommonNoteGraph-en-v1#root> ;
tree:hasSHA256Hash: "92ac6762c129666107299c2386420fdb31b12df7723b3aa0d132485fda864a47" .
<#en-v1.1>
a tree:ShapeTreeDecoratorHierarchy ;
xsd:lang "en" ;
tree:hasVersion "1.1" ;
tree:hasSkosGraph <https://commonnote.example/CommonNoteGraph-en-v1.1#root> ;
tree:hasSHA256Hash: "74a468adf584231d0aa3b3277fd21b13bdf0246832c992701666921c2676ca29" .
<#ru>
a tree:ShapeTreeDecoratorSeries ;
treeIndex:hasHierarchy <#ru-v1> .
<#ru-v1>
a tree:ShapeTreeDecoratorHierarchy ;
xsd:lang "ru" ;
tree:hasVersion "1.0" ;
tree:hasSkosGraph <https://commonnote.example/CommonNoteGraph-ru-v1#root> ;
tree:hasSHA256Hash: "7d8cf659fdbd69618658e043c2c6e8c8e9395f4b652a38c2e5922eb7a51de42c" .
</pre>
</figure>
<figure>
<figcaption>Sample SKOS graph <code>(<#en-v1>)</code>, in English, defining the terms in the CommonNotes shape tree</figcaption>
<pre highlight="turtle">
@prefix f: </data/CommonNotesShapeTree#container> .
@prefix tree: <http://www.w3.org/ns/shapetree#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
<#root> a tree:ShapeTreeLabel ; tree:hasShapeTree f:root ; skosxl:prefLabel [ skosxl:literalForm "Note Container"@en ] ; skos:narrower <#note> .
<#note> a tree:ShapeTreeLabel ; tree:hasShapeTree f:note ; skosxl:prefLabel [ skosxl:literalForm "Text content of a note"@en ] ; skos:narrower <#citation>, <#image> .
<#citation> a tree:ShapeTreeLabel ; tree:hasShapeTree f:citation ; skosxl:prefLabel [ skosxl:literalForm "Citation to another document within a note"@en ] .
<#image> a tree:ShapeTreeLabel ; tree:hasShapeTree f:citation ; skosxl:prefLabel [ skosxl:literalForm "Embedded image or graphic within a note"@en ] .
</pre>
</figure>
<figure>
<figcaption>Sample SKOS graph <code>(<#ru-v1>)</code>, in Russian, describing the same CommonNotes shape tree:</figcaption>
<pre highlight="turtle">
@prefix f: </data/CommonNotesShapeTree#container> .
@prefix tree: <http://www.w3.org/ns/shapetree#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
<#root> a tree:ShapeTreeLabel ; tree:hasShapeTree f:root ; skosxl:prefLabel [ skosxl:literalForm "контейнер для заметок"@ru ] ; skos:narrower <#note> .
<#note> a tree:ShapeTreeLabel ; tree:hasShapeTree f:note ; skosxl:prefLabel [ skosxl:literalForm "текстовое содержание заметки"@ru ] ; skos:narrower <#citation>, <#image> .
<#citation> a tree:ShapeTreeLabel ; tree:hasShapeTree f:citation ; skosxl:prefLabel [ skosxl:literalForm "Цитирование другого документа в заметке"@ru ] .
<#image> a tree:ShapeTreeLabel ; tree:hasShapeTree f:citation ; skosxl:prefLabel [ skosxl:literalForm "Встроенное изображение или изображение в заметке"@ru ] .
</pre>
</figure>
Definitions {#definitions}
=====================
**All definitions as stated below should be considered in the context of shape trees, whether explicitly stated or not.**
The <dfn>Plant</dfn> Operation represents the act of marking a new or existing container as being managed by one or more shape tree.