# 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: ;rel="preserve"' \ -d " ." ``` ## 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: ; 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: . <> a solid:InsertDeletePatch; solid:inserts { . }.' ``` 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: . @prefix ldp: . @prefix posix: . @prefix xsd: . a ldp:Container, ldp:BasicContainer, ldp:Resource; dc:modified "2022-06-09T08:17:07.000Z"^^xsd:dateTime; ldp:inbox ;. ``` 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/' ``` ```shell HTTP/1.1 200 OK Link: ; rel="http://www.w3.org/ns/ldp#inbox" ```