-
Notifications
You must be signed in to change notification settings - Fork 21
Resource Management
The primary mechanism for creating, updating and deleting resources is defined by the W3C Linked Data Platform (LDP) specification. For those unfamiliar with LDP, an introductory primer is available.
In brief, all resources can be managed with standard HTTP methods: GET
for retrieval, POST
for creation, PATCH
for modification of RDF resources, PUT
for replacing content, DELETE
for removing content. In addition HEAD
and OPTIONS
are very useful for determining the capabilities of a given resource.
GET /repository/resource HTTP/1.1
RDF-based resources support content negotiation: representations can be requested in text/turtle
, application/n-triples
and application/ld+json
. In addition, an HTML representation is provided for user convenience.
When Non-RDF (binary) resources are added, a corresponding RDF resource is created. Link
headers will lead a client to that resource.
That is, if you create an LDP-NR at http://www.example.com/binary
and then try to fetch the resource from that URL, you will see a link header for:
Link: <http://www.example.com/binary?ext=description>; rel="describedby"
Requesting the URL from that Link header, you get the description. That description contains these headers:
Link: <http://www.example.com/binary>; rel="describes"
Link: <http://www.example.com/binary?ext=description>; rel="canonical"
Link: <http://www.example.com/binary#description>; rel="alternate"
Note the rel="alternate"
— an HTTP server will ignore a fragment in a request path, which means that this "alternate" URL is functionally equivalent to the binary's URL when it comes to matching the resource path.
For example, if you request a LDP-NR http://www.example.com/binary
using an Accept
header such as text/turtle
, you'll get the description. You can PATCH
to that URL with SPARQL Update, though the Accept-Patch
header is only returned when the description is returned.
The reason for this convolution has to do with RDF contexts: if you PATCH
to the description with <>
, we want that to expand to the value of the request URL itself, but we also want the subject of the RDF to be the LDP-NR, and the only way to do that is with this sleight of hand where the request URL context is the same as the LDP-NR while also ensuring that the LDP-NR and its description are available at separate URLs. The ?ext=description
will only ever respond with RDF.
In general, when an RDF representation is desired, a client should include an Accept
header in the request:
Accept: application/ld+json;q=1.0, text/turtle;q=0.5
The default representation of a resource will contain user-managed triples, containment triples (if any) and membership triples (if any). By using a Prefer
header in the request, it is possible to manipulate which triples to include or exclude from that representation. It is also possible to add categories of triples that are typically excluded from responses, such as audit triples:
Prefer: return=representation; include="http://www.trellisldp.org/ns/trellis#PreferAudit"
More information about using Prefer
headers can be found in the LDP specification.
Using POST
:
When a client creates a resource, it is recommended that the request include a Link
header defining the LDP resource type to be created along with the Content-Type
of the request:
POST /container/ HTTP/1.1
Link: <http://www.w3.org/ns/ldp#RDFSource>; rel="type"
Content-Type: application/ld+json
Slug: resource
In the absence of a Link
header, Trellis will guess the LDP resource type based on the Content-Type and/or request body. The default type for RDF-based resources is LDP-RS
. The Slug
header provides a client-supplied hint for the new resource. That value may not contain slashes or other invalid characters. In the absence of a Slug
header, a unique identifier will be generated automatically. The response will include a Location
header with the URL of the new resource along with the LDP type of the resource:
Location: https://example.org/container/resource
Link: <http://www.w3.org/ns/ldp#RDFSource>; rel="type"
Using PUT
:
POST /container/resource HTTP/1.1
Link: <http://www.w3.org/ns/ldp#RDFSource>; rel="type"
Content-Type: application/ld+json
It is also possible to create resources with PUT
. Doing so, however, may lead to a disconnected graph of resources, as any intermediate containers will not be generated automatically. If a client wishes to avoid this situation, the client should use only POST
for resource creation.
Using PATCH
:
PATCH /container/resource-1 HTTP/1.1
Content-Type: application/sparql-update
If-Match: "aeb02953618b318fde4a1b162f138b77b981c71c"
RDF resources can be modified in-place with the HTTP PATCH
method. Trellis supports the application/sparql-update
content type for this, which is a standards-based mechanism for modifying RDF documents. Binary resources do not allow PATCH
on the resource bitstream, but they do allow PATCH
for modifying the corresponding RDF description.
Using PUT
:
PUT /container/resource-1 HTTP/1.1
Content-Type: application/ld+json
If-Match: "aeb02953618b318fde4a1b162f138b77b981c71c"
When modifying an existing resource with PUT
or PATCH
, it is recommended that a client use an If-Match
header along with the ETag identifier for the resource. Note: the supplied ETag value must be a strong ETag, even if the resource generally responds with a weak ETag value.
It is possible to modify the LDP Resource type with PUT
so long as the new type is a subtype of the existing resource. To do this, an appropriate Link
header would need to be supplied. Trellis will respond with an error if the new LDP type is not a subtype of the existing resource.
DELETE /container/resource-1 HTTP/1.1
A resource can be deleted with the HTTP DELETE
method. It is worth noting that recursive deletes are not supported, and so a DELETE
operation on a resource that contains child resources will result in the deletion of the target resource but no change to the child resources. This can lead to a disconnected graph of resources, and so a client wishing to avoid this possibility will need to first walk the resource hierarchy before deleting resources. It is also recommended to first manipulate the ACL resources of the resources in the hierarchy, preventing any modification while the DELETE
is in-flight.