-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathhttp-api.ttl
More file actions
281 lines (273 loc) · 17.5 KB
/
Copy pathhttp-api.ttl
File metadata and controls
281 lines (273 loc) · 17.5 KB
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
@prefix ldh: <https://w3id.org/atomgraph/linkeddatahub#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dh: <https://www.w3.org/ns/ldt/document-hierarchy#> .
@prefix dct: <http://purl.org/dc/terms/> .
<> a dh:Item ;
dct:title "HTTP API" ;
dct:description "Learn how to access and manage RDF data over generic HTTP API" ;
rdf:_1 <#content> .
<#content> a ldh:XHTML ;
rdf:value """<div xmlns="http://www.w3.org/1999/xhtml">
<p class="lead">Learn how to read and write RDF data from/to LinkedDataHub applications over HTTP</p>
<p>LinkedDataHub implements a uniform, generic RESTful Linked Data API as defined by the
<a href="https://www.w3.org/TR/sparql11-http-rdf-update/" target="_blank">SPARQL 1.1 Graph Store Protocol</a>. It adds a few <a href="#graph-names">conventions</a> and <a href="#constraints">constraints</a>
on top of it however.</p>
<div>
<h2 id="auth">Authentication</h2>
<p>LinkedDataHub UI supports 2 authentication methods:</p>
<ul>
<li><a href="https://dvcs.w3.org/hg/WebID/raw-file/tip/spec/tls-respec.html" target="_blank">WebID-TLS</a> using TLS client certificates</li>
<li><a href="https://developers.google.com/identity/protocols/oauth2/openid-connect" target="_blank">OpenID Connect using Google</a></li>
</ul>
<p>See how those authentication methods can be <a href="../configuration/">configured</a> or how to <a href="../../get-started/get-an-account/">get an account</a> on LinkedDataHub.</p>
<div class="alert alert-info">
<p>HTTP API access using <a href="../command-line-interface/">CLI scripts</a> or curl currently does not support the OIDC method.</p>
</div>
</div>
<div>
<h2 id="acl">Access control</h2>
<p>All HTTP access to <a href="#documents">documents</a> is subject to <a href="../administration/acl/">access
control</a>. Requesting a document with insufficient access rights will result in <code>403 Forbidden</code> response. That means either:</p>
<ul>
<li>the user is not authenticated and public access to the document is not allowed</li>
<li>the user is authenticated but the associated agent does not have an authorization to <a href="../data-model/documents/#manage">perform the action</a> on the
requested document</li>
</ul>
</div>
<div>
<h2 id="documents">Managing documents</h2>
<p>Every document is also a <a href="../dataset/#structure">named graph</a> in the application's RDF dataset. LinkedDataHub supports the SPARQL Graph Store Protocol's <a href="https://www.w3.org/TR/sparql11-http-rdf-update/#direct-graph-identification" target="_blank">direct graph identification</a> as the HTTP CRUD protocol for managing document data.</p>
<div class="alert alert-info">
<p>GSP <a href="https://www.w3.org/TR/sparql11-http-rdf-update/#indirect-graph-identification" target="_blank">indirect graph identification</a> is not supported starting with LinkedDataHub version 5.x.</p>
</div>
<p>The API also supports the <code>PATCH</code> HTTP method which is <a href="https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch">optional in GSP</a>. It accepts graph-scoped SPARQL updates that will modify the requested document. Only the <code>INSERT/WHERE</code> and <code>DELETE WHERE</code> forms are supported; <code>GRAPH</code> patterns are not allowed.</p>
<p>Trailing slashes in document URIs are enforced using <code>308 Permanent Redirect</code> responses.</p>
<table class="table">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
<th>Success</th>
<th>Failure</th>
<th>Reason</th>
</tr>
</thead>
<tbody>
<tr>
<th rowspan="2"><code id="ld-get">GET</code></th>
<td rowspan="2">Returns the data of a document</td>
<td rowspan="2"><code>200 OK</code></td>
<td><code>404 Not Found</code></td>
<td>Document with request URI not found</td>
</tr>
<tr>
<td><code>406 Not Acceptable</code></td>
<td><a href="#con-neg">Media type</a> not supported</td>
</tr>
<tr>
<th rowspan="5"><code id="ld-post">POST</code></th>
<td rowspan="5">Appends data to a named graph</td>
<td rowspan="5"><code>204 No Content</code></td>
<td><code>400 Bad Request</code></td>
<td><a href="#con-neg">RDF syntax error</a></td>
</tr>
<tr>
<td><code>404 Not Found</code></td>
<td>Document with request URI not found</td>
</tr>
<tr>
<td><code>413 Payload Too Large</code></td>
<td>Request body too large</td>
</tr>
<tr>
<td><code>415 Unsupported Media Type</code></td>
<td><a href="#con-neg">Media type</a> not supported</td>
</tr>
<tr>
<td><code>422 Unprocessable Entity</code></td>
<td><a href="../administration/ontologies/#constraints">Constraint</a> violation</td>
</tr>
<tr>
<th rowspan="5"><code id="ld-put">PUT</code></th>
<td rowspan="5">Upserts a document</td>
<td rowspan="5"><code>200 OK</code> <code>201 Created</code> <code>308 Permanent Redirect</code></td>
<td rowspan="2"><code>400 Bad Request</code></td>
<td><a href="#con-neg">RDF syntax error</a></td>
</tr>
<tr>
<td>Malformed document URI</td>
</tr>
<tr>
<td><code>413 Payload Too Large</code></td>
<td>Request body too large</td>
</tr>
<tr>
<td><code>415 Unsupported Media Type</code></td>
<td><a href="#con-neg">Media type</a> not supported</td>
</tr>
<tr>
<td><code>422 Unprocessable Entity</code></td>
<td><a href="../administration/ontologies/#constraints">Constraint</a> violation</td>
</tr>
<tr>
<th rowspan="2"><code id="ld-delete">DELETE</code></th>
<td rowspan="2">Removes the requested document</td>
<td rowspan="2"><code>204 No Content</code></td>
<td><code>404 Not Found</code></td>
<td>Document with request URI not found</td>
</tr>
<tr>
<td><code>405 Method Not Allowed</code></td>
<td>Deleting root, owner, or secretary documents is not allowed</td>
</tr>
<tr>
<th><code id="ld-patch">PATCH</code></th>
<td>Modifies a document using SPARQL Update</td>
<td><code>204 No Content</code></td>
<td><code>422 Unprocessable Entity</code></td>
<td>SPARQL update string violates syntax constraints</td>
</tr>
</tbody>
</table>
<div>
<h3 id="document-metadata">Document metadata</h3>
<p>Unlike earlier versions, LinkedDataHub 5.x manages the <a href="../data-model/documents/#hierarchy">document hierarchy</a> automatically.</p>
<p>By default, LinkedDataHub treats an RDF document as an item by giving it the <code>dh:Item</code> type and attaching it to the parent container using <code>sioc:has_container</code>. If the client wants to create a container instead, it has to explicitly add the <code>dh:Container</code> type on the document resource; the new container will be attached to its parent using <code>sioc:has_container</code>. In either case, the URI of the new document's will be relative to its parent's.</p>
<p>LinkedDataHub will also manage additional document metadata, such as its owner and creation/modification timestamps.</p>
<p>For example, this HTTP request to create a new container (Turtle syntax):</p>
<pre><code>PUT /namedgraph/new-container/ HTTP/1.1
Host: linkeddatahub.com
Content-Type: text/turtle
@prefix dh: <https://www.w3.org/ns/ldt/document-hierarchy#> .
@prefix dct: <http://purl.org/dc/terms/> .
<> a dh:Container ;
dct:title "New container" .</code></pre>
<p>will produce the following document triples:</p>
<pre><code>@prefix dh: <https://www.w3.org/ns/ldt/document-hierarchy#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix acl: <http://www.w3.org/ns/auth/acl#> .
<https://linkeddatahub.com/namedgraph/new-container/>
a dh:Container ;
dct:created "2025-03-31T21:46:21.984Z"^^xsd:dateTime ;
dct:creator <https://linkeddatahub.com/namedgraph/admin/acl/agents/fda0009e-191b-4f07-838c-5daf2a74b35f/#this> ;
dct:title "New container" ;
sioc:has_parent <https://linkeddatahub.com/namedgraph/> ;
acl:owner <https://linkeddatahub.com/namedgraph/admin/acl/agents/fda0009e-191b-4f07-838c-5daf2a74b35f/#this> .</code></pre>
<p>The HTTP request to produce a new item can be empty:</p>
<pre><code>PUT /namedgraph/new-container/ HTTP/1.1
Host: linkeddatahub.com
Content-Type: text/turtle</code></pre>
<p>It will create an item document with the following triples:</p>
<pre><code>@prefix dh: <https://www.w3.org/ns/ldt/document-hierarchy#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix acl: <http://www.w3.org/ns/auth/acl#> .
<https://linkeddatahub.com/namedgraph/new-item/>
a dh:Item ;
dct:created "2025-03-31T20:45:42.802Z"^^xsd:dateTime ;
dct:creator <https://linkeddatahub.com/acl/agents/d47e1f9b-c8d0-4546-840f-5d9fbb479da2/#id9d3814f2-53bc-42e9-b1ab-46cbc9a94263> ;
sioc:has_container <https://linkeddatahub.com/namedgraph/> ;
acl:owner <https://linkeddatahub.com/admin/acl/agents/d47e1f9b-c8d0-4546-840f-5d9fbb479da2/#id9d3814f2-53bc-42e9-b1ab-46cbc9a94263> .</code></pre>
</div>
<div>
<h3 id="constraints">Built-in constraints</h3>
<p>LinkedDataHub has a few built-in constraints that are not found in the standard Graph Store Protocol:</p>
<ul>
<li>It's not possible to delete the root document (returns <code>405 Method Not Allowed</code>)</li>
<li>It's not possible to modify or delete the documents of the owner agent and the secretary agent (returns <code>405 Method Not Allowed</code>)</li>
<li>A document can only be created with a URL relative to an existing container (i.e. resolving <samp>..</samp> against the new document's URL must identify an existing container)</li>
</ul>
<p>The built-in constraints are similar to, but separate from the <a href="../administration/ontologies/#constraints">ontology constraints</a>.</p>
</div>
</div>
<div>
<h2 id="sparql">Executing SPARQL</h2>
<p>Every LinkedDataHub application provides a SPARQL endpoint on <code>sparql</code> path (relative to the application's base URI). It supports the
<a href="https://www.w3.org/TR/sparql11-protocol/" target="_blank">SPARQL 1.1 Protocol</a> and serves as a proxy for the backend endpoint of the
application.</p>
</div>
<div>
<h2 id="system-endpoints">System endpoints</h2>
<p></p>
<h3>Admin and end-user apps</h3>
<dl>
<dt><samp>add</samp></dt>
<dd>Reads data from the specified URL location or uploaded file into the specified named graph</dd>
<dt><samp>ns</samp></dt>
<dd>In-memory namespace ontology as well as its SPARQL endpoint</dd>
<dt><samp>transform</samp></dt>
<dd>Reads data from the specified URL location or uploaded file, transforms it using the specified <code>CONSTRUCT</code> query, and stores the result into the specified named graph</dd>
</dl>
<h3>Admin app only</h3>
<dl>
<dt><samp>admin/access</samp></dt>
<dd>Access metadata (for the authenticated agent)</dd>
<dt><samp>admin/access/request</samp></dt>
<dd>Access request (for the authenticated agent)</dd>
<dt><samp>admin/sign%20up</samp></dt>
<dd>WebID-TLS agent signup</dd>
<dt><samp>oauth2/login/google</samp></dt>
<dd>OpenID Connect with Google login</dd>
<dt><samp>oauth2/login/orcid</samp></dt>
<dd>OpenID Connect with ORCID login</dd>
<dt><samp>oauth2/authorize/google</samp></dt>
<dd>OpenID Connect with Google callback</dd>
<dt><samp>oauth2/authorize/orcid</samp></dt>
<dd>OpenID Connect with ORCID callback</dd>
<dt><samp>admin/clear</samp></dt>
<dd>Clears the specified ontology from memory cache and reloads it from the admin SPARQL endpoint</dd>
<dt><samp>packages/install</samp></dt>
<dd>Installs a package. Requires owner/admin authentication</dd>
<dt><samp>packages/uninstall</samp></dt>
<dd>Uninstalls a package. Requires owner/admin authentication</dd>
</dl>
</div>
<div>
<h2 id="ld-proxy">Linked Data proxy</h2>
<p>LinkedDataHub works as a <dfn>Linked Data proxy</dfn> (from the end-user perspective, as a <dfn>Linked Data browser</dfn>) when a URL is provided using the <code>uri</code> query parameter.
All HTTP methods are supported.</p>
<p>If the URL dereferences successfully as RDF, LinkedDataHub forwards its response body (re-serializing it to enable content negotiation).
During a write request, the request body is forwarded to the provided URL.</p>
<p>The proxy only accepts external (non-relative to the current application's base URI) URLs; local URLs have to be dereferenced directly.</p>
</div>
<div>
<h2 id="con-neg">Content negotiation</h2>
<p>LinkedDataHub implements <a href="https://tools.ietf.org/html/rfc7231#section-3.4.1" target="_blank">proactive conneg</a> based on the request <code>Accept</code>
header value. The following RDF media types are supported (for requests as well as responses, unless indicated otherwise):</p>
<ul>
<li><a href="https://www.w3.org/TR/turtle/" target="_blank">Turtle</a> <code>text/turtle</code></li>
<li><a href="https://www.w3.org/TR/n-triples/" target="_blank">N-Triples</a> <code>application/n-triples</code></li>
<li><a href="https://www.w3.org/TR/rdf-syntax-grammar/" target="_blank">RDF/XML</a> <code>application/rdf+xml</code></li>
<li><a href="https://www.w3.org/TR/json-ld/" target="_blank">JSON-LD</a> <code>application/ld+json</code></li>
<li><a href="https://atomgraph.github.io/RDF-POST/" target="_blank">RDF/POST</a> <code>application/x-www-form-urlencoded</code> (for requests only)</li>
</ul>
</div>
<div>
<h2 id="errors">Error responses</h2>
<p>LinkedDataHub provides machine-readable error responses in the requested RDF format. An example of <code>403 Forbidden</code>:</p>
<pre><code>@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix http: <http://www.w3.org/2011/http#> .
@prefix sc: <http://www.w3.org/2011/http-statusCodes#> .
@prefix dct: <http://purl.org/dc/terms/> .
[ a http:Response ;
dct:title "Access not authorized" ;
http:reasonPhrase "Forbidden" ;
http:sc sc:Forbidden ;
http:statusCodeValue "403"^^xsd:long
] .</code></pre>
</div>
<div>
<h2 id="caching">Caching</h2>
<p><code>GET</code> and <code>HEAD</code> RDF responses from the backend triplestores (<em>not LinkedDataHub responses</em>) are cached automatically by LinkedDataHub using <a href="https://varnish-cache.org" target="_blank">Varnish</a>
as HTTP proxy cache. You can check the age of the response by inspecting the <code>Age</code> response header (the value is in seconds).</p>
<p>LinkedDataHub sends <code>ETag</code> response headers that are derived as hashes of the requested document's RDF content. Every serialization format (HTML, RDF/XML, Turtle etc.) gets a distinct <code>ETag</code> value.</p>
<p>Caching of LinkedDataHub responses can be enabled on the nginx HTTP proxy server by uncommenting the <code>add_header Cache-Control</code> directives in the <samp>platform/nginx.conf.template</samp> file.
Caching of <samp>/uploads/</samp> and <samp>/static/</samp> namespaces is enabled by default (since version 4.0.4).</p>
</div>
</div>"""^^rdf:XMLLiteral ;
rdfs:seeAlso <https://www.w3.org/TR/sparql11-http-rdf-update/> .
<https://www.w3.org/TR/sparql11-http-rdf-update/> dct:title "SPARQL 1.1 Graph Store HTTP Protocol".