Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify POST #108

Closed
csarven opened this issue Nov 4, 2019 · 44 comments
Closed

Specify POST #108

csarven opened this issue Nov 4, 2019 · 44 comments

Comments

@csarven
Copy link
Member

csarven commented Nov 4, 2019

In context of LDP, POST is used to add resources to containers ie. POST to LDPC resource optionally using the Slug header and Link for interaction model(s).

What should be the POST behaviour to target resources that are not LDPCs?

POST /foo/bar

If the target resource exist, what should happen?

If the target resource doesn't exist, what should happen?

What are the effects of interaction model(s) (LDPR and/or LDPC) used in request's Link header?

How should requests to create a resource with the LDP-NR interaction model get handled?

What are the effects without an interaction model?

@acoburn
Copy link
Member

acoburn commented Nov 4, 2019

I am happy to adjust the Trellis behavior to whatever gets specified here, but I will describe the current behavior in the context of your questions.

What should be the POST behaviour to target resources that are not LDPCs?

If the target resource exist, what should happen?

Respond with 405 Method Not Allowed

What should be the POST behaviour to target resources that are not LDPCs?

If the target resource doesn't exist, what should happen?

Respond with 404 Not Found

What are the effects of interaction model(s) (LDPR and/or LDPC) used in request's Link header?

For a successful request (i.e. /foo/bar is an LDP-C) the link header would define the interaction model for the newly created resource. A successful response will echo that interaction model back to a client in a Link header.

How should requests to create a resource with the LDP-NR interaction model get handled?

The body of the request (the raw byte stream) is used to create the new resource at the location hinted at with a Slug header (or at a server-generated location in the absence of a Slug header). A successful request will respond with the following:

  • A Location header pointing to the new resource's URL
  • A Link header with the interaction model of the new resource (i.e. LDP-NR)
  • A Link header pointing to the location of the corresponding LDP-RS description of this LDP-NR (every LDP-NR has an LDP-RS description)

What are the effects without an interaction model?

The server uses implementation-specific heuristics to assign an interaction model. I.e. if the Content-Type request header is an RDF serialization that is parseable by the server as RDF, the new resource is assigned an LDP-RS interaction model; otherwise, the resource is assigned an LDP-NR interaction model.

@csarven
Copy link
Member Author

csarven commented Nov 14, 2019

Raised by @ericprud ( https://gitter.im/solid/specification?at=5dcd102092a84f79fe6477bb ):

Should a 201 response payload include statements related to adding a new resource to a container eg. mention other created resources (nested containers) and the relations between them, metadata, associated shapes..

@kjetilk
Copy link
Contributor

kjetilk commented Dec 19, 2019

Indeed, LDP defines POST only for creation, which has always baffled me, since "Annotation existing documents; [...] Extending a document during authorship." has been part of POST semantics since the dawn of ages. Especially with RDF, where append is clearly defined in terms of RDF Merge (which is basically just a union where you relabel blank nodes so that they don't crash). I think it is important that we do better than LDP in this area, because POST-to-append is very common practice (though, I might have lost touch with devs). Moreover, it seems to me that POST operations will only need acl:Append privileges (with minor exceptions), as they all append operations, right?

So, my proposal follows somewhat like the setup of #40 :

  • Container
  • RDF source
    • Creation: MUST be supported with Slug as defined elsewhere, with If-None-Match: * also supported.
    • Update: MUST be supported, where the payload is appended to the representation using RDF Merge.
    • SPARQL Support: Currently discussed in Level of SPARQL Update support #125 .
  • Non-RDF Source:
    • Creation: MUST be supported with Slug as defined elsewhere, with If-None-Match: * also supported.
    • Update: MAY be supported if the server is able to support an append operation on the media type.
  • ACL resources
    • Like RDF sources, but with acl:Control required instead of acl:Append.

@kjetilk kjetilk moved this from To Do to Under discussion in Specification Dec 19, 2019
@csarven
Copy link
Member Author

csarven commented Jan 5, 2020

For a HTML representation (#69), it will replace the HTML, but not the RDF, in which case acl:Write is required.

By "RDF", are you referring to server-managed triples or the other representations of the same resource?

Why [POST] "replace" exactly? RDF Source or Non-RDF Source Update cases use append.

Requiring different access modes, depending on Content-Type and optionally Link headers, seems awkward. Is there even a way to set a policy like that in ACL? Otherwise, setting acl:Write on the container (and by default its members) just so that it can be updated in HTML seems problematic.

Besides those concerns, I agree with the setup.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 6, 2020

For a HTML representation (#69), it will replace the HTML, but not the RDF, in which case acl:Write is required.

By "RDF", are you referring to server-managed triples or the other representations of the same resource?

I was thinking the entire RDF representation, to easily distinguish in a non-LDPy way...

Why [POST] "replace" exactly?

Simply because POST is fluffily enough defined to be used this way without breaking a spec... :-)

RDF Source or Non-RDF Source Update cases use append.

Requiring different access modes, depending on Content-Type and optionally Link headers, seems awkward. Is there even a way to set a policy like that in ACL? Otherwise, setting acl:Write on the container (and by default its members) just so that it can be updated in HTML seems problematic.

Yeah, I agree, it is awkward. My thinking is that you would most probably usually replace the HTML representation (#69 ), editions is managed client side, so you GET the resource, make your edits and replace the resource... So, you'd want PUT really, but since you can never replace the whole representation because of the server-managed triples, you can't have PUT, so I gave POST this role instead...

If we resolve that you can replace an HTML representation through PUT (#40) without touching the RDF or at least the server managed triples, then this can go. I'm not sure which is the lesser of evils.

@csarven
Copy link
Member Author

csarven commented Jan 6, 2020

I was thinking the entire RDF representation, to easily distinguish in a non-LDPy way...

I don't understand. Can you please clarify?

Yeah, I agree, it is awkward.

If representations have their URLs, it would be possible to set different access modes. However, the direction we are taking sets the policy on the effective request URI which applies to all representation URLs.

Simpler to keep all POST updates to append.

I'm not sure which is the lesser of evils.

I don't see the key difference. Both approaches essentially attempt to replace a container that way. Looking at it from the other direction, if so desired, the same rule can be applied to POST, PUT, PATCH ie. don't allow server-managed triples to be altered, irrespective of the mediatype. Possible to just ignore or fail universally.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 7, 2020

I was thinking the entire RDF representation, to easily distinguish in a non-LDPy way...

I don't understand. Can you please clarify?

OK. If we say "server-managed triples" that references the LDP specification, an implementation has to understand what is meant by that, if we say "entire RDF representation", that's just a media type, much less to understand. However, I suppose what makes the actual complexity is something we will find out when we write the spec, it is thus something we can defer until the drafting phase.

Yeah, I agree, it is awkward.

If representations have their URLs, it would be possible to set different access modes. However, the direction we are taking sets the policy on the effective request URI which applies to all representation URLs.

My main concern is that the security usability around access modes for different representation URLs is going to be really bad unless we put a lot of effort into it. We then have to make sure the end result when managing authz isn't confusing. That's not to say that we shouldn't resolve #109 , it is just that it is a much bigger topic when authz is involved. If we just have the container URL, and all manipulations are on that, it is much easier, you know exactly what rules apply.

Simpler to keep all POST updates to append.

I'm not sure which is the lesser of evils.

I don't see the key difference. Both approaches essentially attempt to replace a container that way. Looking at it from the other direction, if so desired, the same rule can be applied to POST, PUT, PATCH ie. don't allow server-managed triples to be altered, irrespective of the mediatype. Possible to just ignore or fail universally.

The key difference is that PUT expects to replace everything, whereas POST doesn't.

@csarven
Copy link
Member Author

csarven commented Jan 7, 2020

If we just have the container URL, and all manipulations are on that, it is much easier, you know exactly what rules apply.

So we agree. Shouldn't design to have representations with different access modes.

The key difference is that PUT expects to replace everything, whereas POST doesn't.

I meant beyond the literal difference between POST and PUT. If POST HTML is spec'd to act like a write/replace operation, it will generally have the same affect as PUT anything to write/replace. And so they both have to deal with not touching the RDF/server-managed triples.

@csarven
Copy link
Member Author

csarven commented Jan 9, 2020

Create a new resource in / (root container):

POST /

<> rdfs:label "foo".

201
Location: /foo

It is not possible to append information to / with POST. Must use PUT or PATCH to change the state of /.

Create /foo/ or append to /foo/ if exists:

POST /
Slug foo/

<> rdfs:label "foo".

Slug is required in order to append information to container with POST.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 9, 2020

Is this in a current implementation, or do you intend it as a normative statement?

@csarven
Copy link
Member Author

csarven commented Jan 9, 2020

It is what I've inferred from the foundations.

POST to target resource that's a container will add a new resource to a container. So, how can the root container be targeted for the purpose of update (append)?

I'm not aware of a server allowing a root container update (append) with POST, so that's within normal behaviour. To close any potential gaps, the question would be if updating the root container should be prohibited with POST. If PUT and PATCH can and allowed, it is probably fine with POST as well. We can devise a way of course but it doesn't seem to be possible at the moment.

For non-root containers, it would be possible to update the container via Slug as the constructed effective request URI would be the desired container, although not necessarily guaranteed if for instance the server doesn't implement Slug or ignores it (aside: we can come back to that exact requirement). I'm not aware of a server capable of updating a non-root container with POST+Slug.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 9, 2020

Oh, I can see it now, you're right... I was confused, because I didn't understand what was appending to a resource and what was creating a resource (which is also appending a container).

I my proposal, your first example would append that triple to the root container RDF representation. And that is, I acknowledge, inconsistent with what I said, that a POST without a Slug would leave the server to determine the URL of the resource it created...

I don't think we should prohibit POST on any container, the question is really whether the behaviour should be

POST /

<> rdfs:label "foo".

201 Created
Location /some-server-generated-url/

or to append <> rdfs:label "foo". to the container RDF representation. I think this would be valid for all containers, irrespective of whether it is a root container or not.

The former is a practice that has been common for a very long time on the Web but doesn't have a spec behind it AFAIK, the latter is a relatively novel interpretation of an old non-normative spec statement.

I suspect the former is already implemented, I'll write a test for it...

@csarven
Copy link
Member Author

csarven commented Jan 9, 2020

whether the behaviour should be
POST /
Location /some-server-generated-url/

That's it. What I'm saying is that - based on agreed foundations - I don't see "append [payload] to the container RDF representation" possible unless Slug is purposed to target the desired effective request URI. Obviously that's not possible for the root container case as it stands. Either the request needs to pass additional information about the intention or we acknowledge that it is not possible to update root container with POST.

The former is a practice

I'm not certain but that practice probably didn't permit more than one operation on the same effective request URI.

@csarven
Copy link
Member Author

csarven commented Jan 9, 2020

How about using POST with Slug: . (dot segment) to suggest that the payload should be appended to the target container:

POST /
Slug: .

<> rdfs:label "foo".


GET /

<> rdfs:label "foo".
...

That is for any container.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 9, 2020

Interesting idea! Just one thing: Currently, Slug is used when creating new resources, not when appending to an existing resource.

So, how about using Slug: * when the server is asked to create the identifier?

Downside of that would be if the feature is already implemented, it would be a breaking change.

@csarven
Copy link
Member Author

csarven commented Jan 9, 2020

I agree that the RFC wording emphasises create but append is not particularly prohibited.

Server is already expected to create the identifier without Slug.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 9, 2020

Right. OK, so we have a couple of possibilities. Those are things that shouldn't block us from advancing to rought consensus, I think. Any other things that block us from that?

@csarven
Copy link
Member Author

csarven commented Jan 9, 2020

No blockers. Some aspects will be worked out in drafting.


By the way, appending with POST text/html is possible and generally useful with RDFa but not so with non-RDFa. POST text/html to an existing container should be interpreted as an append operation based on request's payload in RDFa - effectively allowing RDF Merge. If the payload doesn't encode an RDF graph, there is nothing to append.

@kjetilk kjetilk moved this from Under discussion to Rough consensus in Specification Jan 10, 2020
@kjetilk
Copy link
Contributor

kjetilk commented Jan 10, 2020

Tested, and found that

solid:handlers POST -- On parent: / +0ms
solid:handlers POST -- Will create at: https://robin.kjernsmo.net:8446/2d4a6a90-33aa-11ea-bd8c-eb7f2690efb0 +0ms

i.e., NSS creates a resource with a server-assigned identifier if no Slug is set. This is as expected, and that would influence the design as we should probably not break this behaviour. I'll update #128 too.

@TallTed
Copy link
Contributor

TallTed commented Jan 10, 2020

[@csarven] POST text/html to an existing container should be interpreted as an append operation based on request's payload in RDFa - effectively allowing RDF Merge

I do not understand the consistant effort to treat anything-but-RDF as trash.

RDFa must not be treated as RDF-plus-HTML, nor otherwise be handled as if the HTML is valueless. RDFa is HTML-plus-RDF, and the primary value of the resource is in the HTML, which value is increased by the inclusion of the RDF.

RDF Merge is not appropriate for POST of any HTML, including HTML-plus-RDF.

POST text/html to an existing container should generally be treated as a request to create a text/html resource within that container -- or maybe as a request for that payload to be handled according to that container's rules, which might include loading RDF found within RDFa markup within that HTML into a triple/quad store -- but should absolutely not include discarding the HTML markup containing the RDFa markup unless that discard follows an explicit confirmation with the user.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 10, 2020

POST text/html to an existing container should be interpreted as an append operation based on request's payload in RDFa - effectively allowing RDF Merge

I do not understand the consistant effort to treat anything-but-RDF as trash.

I do not understand how anything that we've said can be interpreted as that. To the contrary, this effort is motivated by a "homepage" use case, where a user wants to write a homepage in HTML.

RDFa must not be treated as RDF-plus-HTML, nor otherwise be handled as if the HTML is valueless. RDFa is HTML-plus-RDF, and the primary value of the resource is in the HTML, which value is increased by the inclusion of the RDF.

Of course.

RDF Merge is not appropriate for POST of any HTML, including HTML-plus-RDF.

Why do you say that?

POST text/html to an existing container should generally be treated as a request to create a text/html resource within that container

Of course, just as we've specified.

-- or maybe as a request for that payload to be handled according to that container's rules, which might include loading RDF found within RDFa markup within that HTML into a triple/quad store --

Yes, that's what we've been saying. What algorithm do you want to use for that if you do not want to use RDF Merge?

but should absolutely not include discarding the HTML markup containing the RDFa markup unless that discard follows an explicit confirmation with the user.

Of course.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 13, 2020

I think we got on some tangents too many now.

In the case of RDF, the append operation is obvious, it is the RDF Merge defined in rdf-mt, for HTML I imagine there could be something similar that defines it in terms of the tree structure, but in general it is far from that obvious and I think we should resist any temptation to define what an append operation means generically, that has to be an orthogonal issue, IMHO outside the scope of Solid. If we start to get too deeply into that, it will slow our progress dramatically.

We have encountered many tensions in #69 , and some of that carries over here, especially since an update of a resource with an HTML+RDFa representation have both types of data. We could trivially append RDF to the resource, but not to HTML. Pragmatically, it seems like something that could be handled as an implementation detail, as the server would always have a way to serialize the RDF regardless of how it has been has added, it could at the very least add it to the /html/head of the document.

I think the critical question is whether POST should tie very strongly to acl:Append. Doing so, would certainly make it easier to secure the server. However, it might be that people use POST to update e.g. HTML files. If so, it is possible to define that when a POST brings a clearly defined append operation and where the server is able to verify that indeed only append is done, like it is for RDF, then it will execute, otherwise it will require acl:Write. It seems like this complexity is unnecessary though: We should insist that POST is used for appends, and only for media types that has a clear append definition. This makes extending the server with further append operations on other media types an orthogonal issue.

In the HTML+RDFa case, it means that changes using RDF only media types will be accepted since they can be dealt with by an RDF Merge, whereas changes in the HTML media types will be rejected.

I believe that we should take the view that POST implies acl:Append is required, and that no operations that require other permissions should be permitted to use POST (ignoring SPARQL for the moment).

@kjetilk
Copy link
Contributor

kjetilk commented Jan 13, 2020

@acoburn :

But generally, why wouldn't you just use PATCH to append triples? application/sparql-update doesn't need to be the only content-type accepted for PATCH.

As mentioned above, POST-to-append has been the intuition since the first HTTP draft. Anecdotally, I have always used it. It maps very clearly to the RDF Merge, which is also how SPARQL defines it. Arguably, INSERT DATA is syntactic sugar around the RDF Merge. I fear, however, that if we give developers another thing to learn beyond RDF to do something as simple as this, it will hinder Solid adoption.

There's nothing wrong with PATCH, but if you only need append, it will always be extra complexity. For example, what access mode is required by a PATCH can only be found from the request body, whereas for POST, it can be found from the media type itself.

So, in the interest of keeping simple things simple and hard things possible, I really think we need to have POST-to-append.

But yeah, I see that Slug: . is less than ideal. I would prefer to not have that design, but I can't come up with a better alternative. That said, since a Container expects much less interaction than other resources, I can certainly live with that we don't define how to add triples to them in this round.

Then, understanding the implications of a POST becomes a matter of inspecting the request URI and applying the heuristics of #128 , which I think is becoming pretty clear, and should improve in the drafting phase.

@csarven
Copy link
Member Author

csarven commented Jan 13, 2020

I think we got on some tangents too many now.

What followed from the point of agreement at #108 (comment) was about container updates.. because it wasn't addressed. That's why I raised and the discussion moved. Whether it is possible to target a container for update with POST:

Just so that we don't get ahead of ourselves, I suggest that we agree on how to target the container for the purpose of updating (appending) its state.

Re:

we should resist any temptation to define what an append operation means generically

RFC doesn't restrict POST append to a Content-Type. So, if anything that's going on is Solid constraining the append to only RDF formats. But even for Solid, I was under the impression that append is not limited to RDF.. I see no reason provided that each use their own request semantics/algo. If we acknowledge that a container may not necessarily be an RDF Source, then we have to consider whether append is supposed to be about RDF or not. Having said that, if POST to append is only for RDF:

Alternatively, we only specify appends to existing containers if server can eventually perform RDF Merge, and that they should reject the other cases?

What do you think about #40 (comment) ?

whether POST should tie very strongly to acl:Append

Yes.

I believe that we should take the view that POST implies acl:Append is required, and that no operations that require other permissions should be permitted to use POST (ignoring SPARQL for the moment).

I thought we agreed on that already. Provided that update to container (to create a new resource) can be covered by append: #118 (comment) .

But yeah, I see that Slug: . is less than ideal. I would prefer to not have that design, but I can't come up with a better alternative. That said, since a Container expects much less interaction than other resources, I can certainly live with that we don't define how to add triples to them in this round.

I don't have anything better at the moment either.. and yes, I can live with no container updates as well. It is still though important... giving a container a human-readable label is a natural expectation.

--

Can we wrap this up? We have enough material here for draft criteria. We can resolve the finer details there.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 13, 2020

I think we got on some tangents too many now.

What followed from the point of agreement at #108 (comment) was about container updates.. because it wasn't addressed. That's why I raised and the discussion moved. Whether it is possible to target a container for update with POST:

Just so that we don't get ahead of ourselves, I suggest that we agree on how to target the container for the purpose of updating (appending) its state.

Right, but I took the conversation here as a broader discussion, one that is about what append operations imply on generic resources, not specifically containers.

Re:

we should resist any temptation to define what an append operation means generically

RFC doesn't restrict POST append to a Content-Type.

No, but the RFC doesn't need a strict interpretation, as it doesn't have a concept of access control, so it can afford to be generic, we cannot, because we have to make sure that the acl:Append authorization is respected.

So, if anything that's going on is Solid constraining the append to only RDF formats. But even for Solid, I was under the impression that append is not limited to RDF.. I see no reason provided that each use their own request semantics/algo.

Hmmmm, append is certainly a useful operation on all kinds of resources, but surely, what an append implies certainly comes down to the semantics of the media type, or even the individual representation?

For RDF, we have the luxury of the RDF merge, which is great. For HTML and JSON, you could envision that an append operation implies that the existing representation R is appended to by a payload R' iff R is a strict subtree of R', but what would it mean to append something to an image, and how could you find out?

That's why I say that each media type needs its own append definition. For RDF we have one, lets go for that.

If we acknowledge that a container may not necessarily be an RDF Source, then we have to consider whether append is supposed to be about RDF or not. Having said that, if POST to append is only for RDF:

Alternatively, we only specify appends to existing containers if server can eventually perform RDF Merge, and that they should reject the other cases?

If we restrict ourselves to containers, then yes. For generic resources, I think the definition could be something like "if representation has a clear algorithm for append" or something.

But yeah, I see that Slug: . is less than ideal. I would prefer to not have that design, but I can't come up with a better alternative. That said, since a Container expects much less interaction than other resources, I can certainly live with that we don't define how to add triples to them in this round.

I don't have anything better at the moment either.. and yes, I can live with no container updates as well. It is still though important... giving a container a human-readable label is a natural expectation.

Yeah... it could still be updated by PUT though, first doing a GET, get the Etag, make that change, and PUT it back with If-Matches...

--

Can we wrap this up? We have enough material here for draft criteria. We can resolve the finer details there.

I agree. We will probably better advance with it more concrete now, and I think it is appropriate to put it down in draft text.

@TallTed
Copy link
Contributor

TallTed commented Jan 13, 2020

[@ericprud] I propose the spec follow the definition of POSTing RDF to RDF docs with:

POSTing an HTML payload P to an HTML resource R appends P's html/body/* elements to the end of R'shtml/body.

I haven't digested everything subsequent to this yet, but this is important --

html/body/* is not all that may be important in an HTML payload. That html/body/* may well depend on things in the html/head/* of P which are not in the original R -- and this would lose those things.

@ericprud's formulation must not be put in the spec, as written here.

@ericprud
Copy link

@TallTed , we can't have a generic server do everything that custom POST handler might do. Normally, I'd not want to bother handling POST on HTML at all, but folks seemed motivated to handle POSTs to index files. Given that, I don't see how we can do any more than provide a simple and predictable rule that clients can count on. So sure, clients might want POST to do arbitrarily complex operations; but I don't know how to specify a generic POST operation to do that. Got any ideas?

@kjetilk
Copy link
Contributor

kjetilk commented Jan 13, 2020

Not sure it is POST on HTML that is the central issue, rather handle the RDFa that might be embedded in it, which should be handled like other RDF would.

@ericprud
Copy link

I agree that RDFa is our primary use case, but I don't think the presence or absence of RDFa affects the treatment of HTML. RDFa's value comes in it being interspersed in the HTML (otherwise, you may as well use a script with type=turlte or JSON). Suppose we have an index file:

<html><head><title>My Stuff</title><style></style></head>
  <body>
  <h2 property="http://purl.org/dc/terms/title">Resource 1</h2>
  <p>Date: <span property="http://purl.org/dc/terms/created">2011-09-10</span></p>
</body> </html>

If we want to add Resource 2 and preserve the RDF, we can (in order of increasing effort and controversy):

  • script-only -- not handle RDFa but instead specify merging POSTed script data into a pre-existing script element in the head.
  • strip-RDFa -- like script-only, but promise to extract any RDFa in POSTed HTML. (-.8 'cause it throws away the value of the RDFa.)
  • append-body -- stuff POSTed RDFa somewhere in the body (top, bottom)
  • markup-target -- have a processing instruction specify where to inject the POSTed RDFa.

And of course there's no-HTML-POST -- reject any POSTs with HTML target or body.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 14, 2020

Yes, indeed, the question is not whether it can be done, the question is whether we should, and if we should, then the question is when. My answer is "definitly not now" :-)

To expand on the append-body, this suggest that there is a lot of freedom that servers could have in determining what an append would be, just like shapes for RDF. For example, one resource could determine that an append it its context would be to add another pair of h2 and p in your example, in another, it could be to add another row of data to a table.

I would question if this is a valid use of Solid, since Solid is mostly about manipulating RDF, and have apps that use RDF on the client side. In this case, we add to much smart to the server side.

I don't see markup-target as a major undertaking, but I don't think we should define it, it should be up ot the server to template where they want to inject the RDFa data. They would probably have to do that anyway, but I believe the only normative thing we should say about it, is that the RDF representation has to be there for the #69 case.

@csarven
Copy link
Member Author

csarven commented Jan 14, 2020

[Just laying out some things to consider.. and also for drafting, so bear with me.]

I'd like to clarify some behaviours and variability related to Slug because it seems important.

Assuming container create and/or update are desired with POST. Without the other headers (eg. Link) influencing the identifier, we have:

  • Slug is required to create and update a container.

  • Slug: . is required to update the root container.

A server accepting Slug and keeping the value as is, the response of the following requests should be equivalent:

POST /
Slug: foo/

POST /foo/
Slug: .

That is, /foo/ will be created or updated.

There is however a variability issue (or consideration) in the responses pertaining to effective request URIs where server ignores Slug. Hence, the above example may result in the creation of /foo and /foo/bar respectively. To take another example:

POST /
Slug: .

Client's request may either result in update / or create /foo if Slug is ignored.

So, what a poor client to do? First question is whether this kind of variability should exist in the design.

Let's say it shouldn't. One way a nice server may be able to mitigate unexpected results for the client is to catch some of the cases. For instance, a server may ignore the Slug in determining an identifier, however, if detected, it can check for consistency. So:

POST /
Slug: foo/

Here the client would like to create /foo/. Compared with the earlier behaviour, the server instead of creating /foo, can return 400 (or something else?) if trailing slash in Slug is detected.

Yet another possible server behaviour is where Slug can only be used to update a container and that create will be rejected. Clients need to use PUT (simple) or PATCH (less simple) to create a container. So:

POST /
Slug: foo/

Client's request may either update /foo/ or return 400 if /foo/ exists.

So, this is a matter of client's comfort in dealing with the consequences of using a Slug. Not using it is obvious and simple but there are cases in which it is definitely a nice to have. If create or update container via POST removed, that'd is another simplification.

Almost done: alternatively, we raise the level of Slug requirement so that there is less variance in the responses.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 14, 2020

Actually, it seems I would want to challenge the premises of that post, @csarven :

  • Slug is required to create and update a container.

  • Slug: . is required to update the root container.

My opinion is that Slug is never required, and the definition of Slug seems to imply it is only for creates. So, while I did find the Slug: . interesting, it seems like we are stretching it a bit, but I feel strongly that once a resource is created, we should manipulate it by its own URL, not use a Slug to do it.

Slug: . is an interesting special case, because it says "this resource", but as you show that it brings along ambigiouties, I say we should save it for $later.

For creates, I think we exhausted the space in #128 (comment)

@csarven
Copy link
Member Author

csarven commented Jan 14, 2020

Actually

Actually, I think you may have overlooked the premise and the statements there :)

Put differently, if you still want to be able to create and update a container using POST, Slug is (probably) required (re #108 (comment) )

I feel strongly that once a resource is created, we should manipulate it by its own URL

That'd be great. How? PUT, PATCH is a non issue obviously.

The whole point of observing variability was due to Slug being MAY. And to help figure out where to draw the lines.

I don't think whether Slug can be used for append or not is actually an issue - okay to dismiss the possibility of course. Let me put it this way, we define the append operation but in there we do have some "create" resource happening - at least the context being that a resource is created and added to container. We are using POST for the purpose of append, so whether the Slug is actually constrained to create (like stand alone resources) is a very specific view. (I'm not dismissing or disagreeing .. just saying that our definitions and reasoning is not super clear to make the call on Slug that way.)

@Mitzi-Laszlo Mitzi-Laszlo modified the milestones: December 19th, February 19th Jan 14, 2020
@kjetilk kjetilk moved this from Rough consensus to Under discussion in Specification Jan 14, 2020
@kjetilk
Copy link
Contributor

kjetilk commented Jan 14, 2020

OK, then I don't understand where you are going, but I've returned it to Under discussion to clarify.

In my head it is very simple: Slug is just for creating resources, and #128 defines that exhaustively.

When updating, you don't use a Slug, the append applies to the request-URI, and since a Slugless POST to a container already means that the server chooses the rest of the identifier (also as detailed in #128), we can't append to the container representation without doing something clever.

That Slug: . could be that clever thing to enable that, but lets not do it now to ensure that we can progress towards a draft. We can figure out that something clever later if appending to a container representation is a feature people miss.

That's my position, what's wrong with that picture?

@csarven
Copy link
Member Author

csarven commented Jan 14, 2020

Just to be clear, it makes sense to move to Under Discussion on the basis of us not completely clearing how to POST Container.Update and if so still desired.

As documented above, I was merely exploring the boundaries to find a way to reconcile. So, yes, I do fully understand your position and there is nothing wrong with that picture.

@kjetilk
Copy link
Contributor

kjetilk commented Jan 14, 2020

Hey! You scared the living daylights out of me, @csarven , I thought you were opening a much bigger can of worms!

Is that picture something we can go for as rough consensus?

@kjetilk kjetilk moved this from Under discussion to Rough consensus in Specification Jan 16, 2020
@csarven csarven modified the milestones: February 19th, ~First Public Working Draft Jan 24, 2020
@elf-pavlik
Copy link
Member

Just stating my preference, not intending to reopen any discussions

  • only use POST on LDPC to create new LDPR (server may or may not honor Slug header)
  • use PATCH to update LDP-RS
  • use PUT to update LDP-NR - this leaves all the complexity of modifying HTML or SVG or ... to the client

If above doesn't address requirements motivated by some specific use case I would need to see that specific use case.

Arguably, INSERT DATA is syntactic sugar around the RDF Merge. I fear, however, that if we give developers another thing to learn beyond RDF to do something as simple as this, it will hinder Solid adoption.

I think libraries can take care of DX. I don't see adding different way to accomplish the same thing that much helpful. Especially if it would rely on nuances (eg. Slug header), add extra burden on storage server implementations, and blurry expectations client applications can make about interactions with storage servers.

@ericprud
Copy link

ericprud commented Feb 1, 2020

Don't most of the reasons you'd want to POST and LDP-RS also apply to LDP-NRs?

  1. server manages naming.
  2. injection into a container (whether that be RDF manipulation or some other server state).
  3. (more) defined response codes for when the above works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Specification
  
Done
Development

No branches or pull requests

7 participants