Issue: https://github.com/solid/specification/issues/525
Room: https://meet.jit.si/solid-cg
Datetime: 2023-08-08 13:00 UTC WorldClock
Let us agree that Hypermedia As The Engine Of Application State (HATEOAS) is an indispensible feature of the Web. In the context of a data store, that not only implies that a GET
request on a resource should return all the hypermedia affordances on a resource but also that a user should be able through a PUT
/POST
/PATCH
request create any arbitrary hypermedia affordance on the resource.
Now, consider the situation with Solid Containers:
A POST
request (with slug header) creates a resource in the container which is reflected by creating an ldp:contains
triple in the representation.
A PUT
(and PATCH
) request is not prohibited. Though, as I shall demonstrate, it is unclear whether the request can be used to create RDF reesources only or even non-RDF resource.
In my specific case, I want to support transclusions. The simplest way I can think of doing this is to store relations to external resources as peers to contained resources (a bit like symlinks but spanning the entire web) and statements explaining what the contained resources and linked resources are about (see my Car Example on stackblitz). Realize that I need the contained resources as well because of cascading permissions (and not have broken links in my own domain), so I cannot just make them as linked resources.
But in other cases this representation can be just about anything - html, img etc.
But now what should happen when I make a GET
request on a resource container:
As this behaviour is undefined in the Solid spec, each implementation is doing their own thing. Pavlik captures CSS decisions in the issue thread!
Next, how do you update the resource based on the representation you have received previously?
POST
PUT/PATCH
HTTP/1.1 GET example.org /Car/Steering/
200 OK
Link: </.meta/Car/Steering/>; rel="http://www.w3.org/ns/solid/terms#TBDserverManaged"
</.meta/Car/Steering/horn/>
/containedStuff; rel="http://www.w3.org/ns/ldp#PreferMembership"
</.meta/*/**> only GET, server does AuthZ
</.acl/Car/Steering>; rel="acl"
</Car/Steering/.acl>
</Car/Steering/> ldp:contains </Car/Steering/.acl>
For GET Foo/
Question: how do you link stuff in R with T? Say you delete a container, a triple t
in T, what is your change in R for statements pertaining to t
.
Prefer
header.How about we return a multipart/mixed response with both the representation R and containment triples T in a multipart response. Omit one or the other parts based on the Prefer > return > include header.
How about we content-negotiate on the container URL say foo/
and use the Content-Location
header to redirect the user to another resource. Link relations will always exist. Use the accept and prefer header to request client RDF.
Cons:
Accept=*/*
will redirect typically to Container RDF. A way around this is to examine the user agent and if that is a browser emit HTML (or another non-RDF resource), otherwise emit Container RDF.index.*
(or another chosen by the server) namespaces cannot be used.Resources such as foo/resource
can only be created by POSTing or PUTing from foo/
. Otherwise location relationships will not be recorded. However PUT can be used to replace the resource foo/resource
provided it has the same Accept-*
parameters).
source: https://github.com/solid/web-access-control-spec/issues/85#issuecomment-913456115
Request | Operation | Access Modes | Level |
---|---|---|---|
GET /C/R | Read | acl:Read | Resource |
HEAD /C/R | Read | acl:Read | Resource |
OPTIONS /C/R | Read | acl:Read | Resource |
POST /C/ | Create + Update | acl:Append [1] | Resource, Content |
PUT /C/R + If-None-Match | Create, Read | acl:Write, acl:Read [2] | Resource |
PATCH /C/R + If-None-Match + INSERT | Create, Read | acl:Write, acl:Read [2] | Resource, Content |
POST /C/R | Update | acl:Append (or acl:Write) | Content |
PUT /C/R | Create?, Update | acl:Write [2][3] | Resource |
PATCH /C/R + INSERT | Create?, Update | acl:Write [2][3] | Resource?, Content |
PATCH /C/R + DELETE + INSERT | Create?, Read, Update | acl:Write, acl:Read [2][3] | Resource?, Content [4] |
PATCH /C/R + DELETE | Update, Read | acl:Write, acl:Read | Content |
DELETE /C/ | Delete | acl:Write, acl:Read | Resource |
DELETE /C/R | Delete | acl:Write [5] | Resource |
TODO: incorporate different representations, like homepage case below
example.com
or example.com/foo -> example.com/foo/
Do we think of client managed triples as augmenting Container RDF or more similar to Non RDF representations (as a thing that is logically distinct from container triples)?
Timestamps can trigger recalculation for all the resources up to the root. It can be avoided by including timestamps in link headers or auxiliary resource.
Servers treats PUT as a simple replacement of state [RFC9110]. These state replacement is supposed to be (i.e. SHOULD, not MUST) only for client manages state updates update.
5.2.4.1 LDP servers should not allow HTTP PUT to update a LDPC’s containment triples; if the server receives such a request, it should respond with a 409 (Conflict) status code.
What about idempotency requirements? Since PUT overwrites state completely:
Users may want to have HTML representation of the homepage, which as storage root (container) has the following constraints:
Accept: */*
and no Prefer
) in the headers and HTML as the only representation PUT in the container:
5.2.7.1 LDP servers are recommended to support HTTP PATCH as the preferred method for updating a LDPC's minimal-container triples.
I suppose we do not want to use PATCH to update containment triples but nothing says that in the LDP spec?
LDP Primer uses POST both to create LDP-RS and LDP-NR (non RDF) resources. There are insufficiant examples of LDP-BC.