2022-08-08 09:14:43 +02:00

124 lines
5.0 KiB
Markdown

# Editing metadata of resources
## What is a description resource
[Description resources](https://solidproject.org/TR/2021/protocol-20211217#auxiliary-resources-description-resource)
contain auxiliary information about a resource.
In CSS, these represent metadata corresponding to that resource.
Every resource always has a corresponding description resource
and therefore description resources can not be created or deleted directly.
Description resources are discoverable by interacting with their subject resource:
the response to a `GET` or `HEAD` request on a subject resource
will contain a `describedby` **Link Header** with a URL that points to its description resource.
Clients should always follow this link rather than guessing its URL,
because the Solid Protocol does not mandate a specific description resource URL.
The default CSS configurations use as a convention that `http://example.org/resource`
has `http://example.org/resource.meta` as its description resource.
## How to edit the metadata of a resource
Editing the metadata of a resource is performed by editing the description resource directly.
This can only be done using `PATCH` requests
(see [example workflow](#example-of-a-workflow-for-editing-a-description-resource)).
`PUT` requests on description resources are not allowed,
because they would replace the entire resource state,
whereas some metadata is [protected](https://solidproject.org/TR/protocol#resource-containment) or generated by the server.
Similarly, `DELETE` on description resources is not allowed
because a resource will always have some metadata (e.g. `rdf:type`).
Instead, the lifecycle of description resources is managed by the server.
### Protected metadata
Some metadata is managed by the server and can not be modified directly, such as the last modified date.
The CSS will throw an error (409 `ConflictHttpError`) when trying to change this protected metadata.
### Preserving metadata
`PUT` requests on a resource will reset the description resource.
There is however a way to keep the contents of description resource prior to the `PUT` request:
adding the HTTP `Link` header targeting the description resource with `rel="preserve"`.
When the resource URL is `http://localhost:3000/foobar`, preserving its description resource when updating its contents can be achieved like in the following example:
```shell
curl -X PUT 'http://localhost:3000/foobar' \
-H 'Content-Type: text/turtle' \
-H 'Link: <http://localhost:3000/foobar.meta>;rel="preserve"' \
-d "<ex:s> <ex:p> <ex:o>."
```
## Impact on creating containers
When creating a container the input body is ignored
and performing a `PUT` request on an existing container will result in an error.
Container metadata can only be added and modified by performing a `PATCH` on the description resource,
similarly to documents.
This is done to clearly differentiate between a container's representation and its metadata.
## Example of a workflow for editing a description resource
In this example, we add an inbox description to `http://localhost:3000/foo/`.
This allows discovery of the `ldp:inbox` as described in the [Linked Data Notifications specification](https://www.w3.org/TR/ldn/).
We have started the CSS with the default configuration
and have already created an inbox at `http://localhost:3000/inbox/`.
Since we don't know the location of the description resource,
we first send a `HEAD` request to the resource to obtain the URL of its description resource.
```shell
curl --head 'http://localhost:3000/foo/'
```
which will produce a response with at least these headers:
```shell
HTTP/1.1 200 OK
Link: <http://localhost:3000/foo/.meta>; rel="describedby"
```
Now that we have the URL of the description resource,
we create a patch for adding the inbox in the description of the resource.
```shell
curl -X PATCH 'http://localhost:3000/foo/.meta' \
-H 'Content-Type: text/n3' \
--data-raw '@prefix solid: <http://www.w3.org/ns/solid/terms#>.
<> a solid:InsertDeletePatch;
solid:inserts { <http://localhost:3000/foo/> <http://www.w3.org/ns/ldp#inbox> <http://localhost:3000/inbox/>. }.'
```
After this update, we can verify that the inbox is added by performing a GET request to the description resource
```shell
curl 'http://localhost:3000/foo/.meta'
```
With as result for the body
```turtle
@prefix dc: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix posix: <http://www.w3.org/ns/posix/stat#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
<http://localhost:3000/foo/> a ldp:Container, ldp:BasicContainer, ldp:Resource;
dc:modified "2022-06-09T08:17:07.000Z"^^xsd:dateTime;
ldp:inbox <http://localhost:3000/inbox/>;
<http://www.w3.org/ns/auth/acl#accessControl> <http://localhost:3000/foo/.acl>;
dc:description <http://localhost:3000/foo/.meta>.
```
This can also be verified by sending a GET request to the subject resource itself.
The inbox location can also be found in the Link headers.
```shell
curl -v 'http://localhost:3000/foo/.meta'
```
```shell
HTTP/1.1 200 OK
Link: <http://localhost:3000/inbox/>; rel="http://www.w3.org/ns/ldp#inbox"
```