Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lws10-core/Operations/create-resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The **create resource** operation adds a new [served resource](#dfn-served-resou

New resources are created using POST to a target <a>container</a> URI, with the server assigning the final identifier. Clients MAY suggest a name via the `Slug` header. Clients MAY provide initial user-managed metadata for the new resource by including one or more `Link` headers in the POST request, following the syntax of Web Linking in [[RFC8288]]. Server-managed metadata MUST be generated automatically by the server upon creation and MUST NOT be overridden by client-provided links.

On success, the server MUST return the 201 status code with the new URI in the `Location` header. The server MUST include `Link` headers for key server-managed metadata, including a link to the parent <a>container</a> (`rel="up"`), and a link to the created resource's dedicated <a>linkset resource</a> (`rel="linkset"; type="application/linkset+json"`). Additional links SHOULD include `rel="type"` (indicating `https://www.w3.org/ns/lws#Container` or `https://www.w3.org/ns/lws#DataResource`). The body MAY be empty or include a minimal representation of the resource. All metadata creation and linking MUST be atomic with the resource creation to maintain consistency.
On success, the server MUST return the 201 status code with the new URI in the `Location` header. The server MUST include `Link` headers for key server-managed metadata, including a link to the parent <a>container</a> (`rel="up"`), and a link to the created resource's dedicated <a>linkset resource</a> (`rel="linkset"; type="application/linkset+json"; profile="lws-meta"`). Additional links SHOULD include `rel="type"` (indicating `https://www.w3.org/ns/lws#Container` or `https://www.w3.org/ns/lws#DataResource`). The body MAY be empty or include a minimal representation of the resource. All metadata creation and linking MUST be atomic with the resource creation to maintain consistency.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a profile="..." shifts the problem rather than resolves it. The earlier concern was that an LWS server could not store a DataResource with media type application/linkset+json, but by adding a profile, it means that an LWS server cannot store a DataResoruce with a media type of application/linkset+json; profile="...". And that is true of any arbitrary profile string.

One way around this would involve using Prefer headers. For example:

For a DataResource stored with media type application/linkset+json, a client can request the linkset representation via (as an example):

Prefer: return=representation; include="https://www.w3.org/ns/lws#Linkset"

In this way, for the normal case of a GET request with no special headers, the response would be:

Content-Type: application/linkset+json
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"

The response from a server that supports content negotiation via Prefer headers would be:

Content-Type: application/linkset+json
Link: <https://www.w3.org/ns/lws#Linkset>; rel="type"

which would be sufficient to know that the response is the linkset and not the data resource.

This approach would require the addition of a vocabulary term (e.g. https://www.w3.org/ns/lws#Linkset). An alternative terms may be preferred.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a profile ... means that an LWS server cannot store a DataResource with a media type of application/linkset+json; profile="...". And that is true of any arbitrary profile string.

That depends on how we define the profile, i.m.o... Since we would define the profile ourselves, we can include in its meaning that it is a server-managed resource/representation. Then there is no semantically valid reason why someone would to store a data resource of that type.


The Prefer header is an option I suggested earlier, and indeed avoids your issue as well. However, contrary to the profile parameter, there is afaik no standardized way to indicate in a rel=linkset link that the link set should be requested with such a header.

@pchampin pchampin Jul 6, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could live with this PR (I agree that we could decide that this particular profile is "reserved" for LWS's auxiliary resources).

However, I share @acoburn's concern (which echoes the concerns I expressed on #165) that content-type is not the right place to negotiate between the primary resource from the auxiliary resource.
If we want to provide such a feature, I would suggest something like

GET /some-primary-resource HTTP/1.1
Prefer: auxiliary; rel=linkset

there is afaik no standardized way to indicate in a rel=linkset link that the link set should be requested with [the Prefer header].

Agreed, my proposal above would need to be registered in IANA's Preference Registry.


**POST (to a container URI)** – *Create with server-assigned name:*
Use POST to add a new resource inside an existing <a>container</a>. The server assigns an identifier to the resource, optionally suggested via the `Slug` header. The server MAY honor the Slug header if it does not conflict with naming rules or existing resources. Clients indicate the type of resource to create as follows:
Expand Down Expand Up @@ -54,7 +54,7 @@ In this example, the client is posting to the <a>container</a> `/alice/notes/`.
HTTP/1.1 201 Created
Location: /alice/notes/shoppinglist.txt
Content-Type: text/plain; charset=UTF-8
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json; profile="lws-meta"
Link: </alice/notes/>; rel="up"
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"
Content-Length: 0
Expand All @@ -76,7 +76,7 @@ Link: <https://www.w3.org/ns/lws#Container>; rel="type"
```
HTTP/1.1 201 Created
Location: /alice/notes/
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json; profile="lws-meta"
Link: </alice/>; rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Content-Length: 0
Expand Down
7 changes: 3 additions & 4 deletions lws10-core/Operations/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ All metadata in LWS is expressed as a set of typed links originating from a reso

Metadata distinguishes between resources and their representations, allowing for multiple media types where applicable. For <a>data resources</a>, metadata includes representations, each with mediaType and optional sizeInBytes. For <a>containers</a> and <a>data resources</a> we consider the link to its parent <a>container</a> resource to be part of the metadata of the resource.


**The <a>Linkset Resource</a>**
For each resource in <a>storage</a>, a server MUST make metadata links available as a standalone resource according to [[!RFC9264]].
For each resource in <a>storage</a>, a server MUST make metadata links available as a linkset, according to [[!RFC9264]].
- Discovery: A resource's linkset is discoverable via a Link header with the relation `rel="linkset"`.
- Media Type: A <a>linkset resource</a> MUST be available as `application/linkset+json`.
- Integrity: The 'linkset' link MUST point to a server-managed resource. Updates to the linkset MUST be atomic with associated resource operations to maintain consistency.
- Media Type: A <a>linkset resource</a> MUST be available as `application/linkset+json; profile="lws-meta"`. The `lws-meta` profile allows the server to distinguish between linksets as auxiliary resource and linksets as data resource.
- Integrity: The 'linkset' link MUST point to an <a>LWS resource</a> in the same <a>storage</a>. Updates to the linkset MUST be atomic with associated resource operations to maintain consistency.

**Discovering Metadata**
Clients discover metadata primarily through Link headers in response to GET or HEAD requests.
Expand Down
4 changes: 2 additions & 2 deletions lws10-core/Operations/read-resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 34
ETag: "abc123456"
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json; profile="lws-meta"
Link: </alice/notes/>; rel="up"
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"

Expand Down Expand Up @@ -52,7 +52,7 @@ Assuming the container exists and the client has access:
HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "container-etag-789"
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json; profile="lws-meta"
Link: </alice/>; rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"

Expand Down
8 changes: 4 additions & 4 deletions lws10-core/Operations/update-resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ A client first fetches the linkset and receives its ETag.
```
GET /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Accept: application/linkset+json
Accept: application/linkset+json; profile="lws-meta"
HTTP/1.1 200 OK
Content-Type: application/linkset+json
Content-Type: application/linkset+json; profile="lws-meta"
ETag: "meta-v1"
{
"linkset": [
Expand All @@ -71,7 +71,7 @@ The client now wants to add a license. It constructs a new, complete linkset doc
```
PUT /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/linkset+json
Content-Type: application/linkset+json; profile="lws-meta"
If-Match: "meta-v1"
{
"linkset": [
Expand All @@ -92,4 +92,4 @@ ETag: "meta-v2"
**Summary of Update Rules**
If you want to change only the content of a resource → PUT/PATCH the resource itself.
If you want to change only the links (metadata) of a resource → PUT/PATCH the resource’s associated <a>linkset resource</a>.
If you want to change both content and links → PUT/PATCH the resource itself, including the appropriate Link headers AND 'Prefer: set-linkset'. Setting both is off by default.
If you want to change both content and links → PUT/PATCH the resource itself, including the appropriate Link headers AND 'Prefer: set-linkset'. Setting both is off by default.
4 changes: 2 additions & 2 deletions lws10-core/lws-media-type.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Response (first page):
HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "photos-page1-etag"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"; profile="lws-meta"
Link: </alice/>; rel="up"
Link: </alice/photos/.acl>; rel="acl"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Expand Down Expand Up @@ -111,7 +111,7 @@ Response (middle page):
HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "photos-page2-etag"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"; profile="lws-meta"
Link: </alice/>; rel="up"
Link: </alice/photos/.acl>; rel="acl"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Expand Down
Loading