Re: ldp-ISSUE-91 (rel='type' Link-based interaction): The LDP (REST) interactions must be driven by the rel='type' Link header [Linked Data Platform Spec]

Hi Steve,

On 11/26/2013 02:48 PM, Steve Speicher wrote:
> Hi Alexandre,
>
>
> On Tue, Nov 26, 2013 at 10:18 AM, Alexandre Bertails <bertails@w3.org>
> wrote:
>>
>> Hi Steve,
>>
>>
>> On 11/26/2013 08:25 AM, Steve Speicher wrote:
>>>
>>> Hi,
>>>
>>> On Fri, Nov 22, 2013 at 5:28 PM, Linked Data Platform (LDP) Working
>>> Group Issue Tracker <sysbot+tracker@w3.org
>>> <mailto:sysbot+tracker@w3.org>> wrote:
>>>
>>>      ldp-ISSUE-91 (rel='type' Link-based interaction): The LDP (REST)
>>>      interactions must be driven by the rel='type' Link header [Linked
>>>      Data Platform Spec]
>>>
>>>      http://www.w3.org/2012/ldp/track/issues/91
>>>
>>>      Raised by: Alexandre Bertails
>>>      On product: Linked Data Platform Spec
>>>
>>>      We have already agreed that LDP interactions are not strictly
>>>      hypermedia driven, as we agreed not to define a new media-type for
>>>      LDP. Instead we have a Link header for Resource [1].
>>>
>>>      The problem is that 4.2.10 [1] does not really advertise the LDP
>>>      interaction, just the "LDP support" for the resource, and the
>>>      interaction is currently derived from a { <> a ldp:Container }
>>>      triple (or its absence). That means than I cannot create a simple
>>>      LDPR with that triple _without_ the related interaction model. This
>>>      is wrong.
>>>
>>>
>>> "This is wrong" needs more elaboration in this context.  By creating it
>>> with this type, the client is stating it is that and what the
>>> interaction model is.
>>
>>
>> "This is wrong" regarding what REST is about [2].
>>
>> [2] http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
>
>
> I figured this card was going to be played but I was asking for something a
> bit more specific to the case we are discussing (how that reference in this
> specific case is causing some issue).  I'll touch on it a bit more later.
>
>>
>>
>> We are already playing with the hypermedia thing, some people would
>> argue that we should not say we do REST... Just remember what happened
>> to "SPARQL 1.1 Graph Store HTTP Protocol", which removed all mentions
>> of REST from the specification.
>>
>> We have already decided to use the type-Link header for LDPR, and I
>> just propose here to extend this approach to the LDPC.
>
> To be clear, this is only a response header.  I could see expanding it to
> be include LDPC.  Though adding as a request header, would have to be given
> a bit more consideration.

Right, LDP currently requires the type-rel (Link Relation Type) only
as a response header. So to be clear, with this proposal, the type-rel
would be required for both directions (response and request header),
and would become the one signaling mechanism for a client or server to
identify an LDPR and an LDPC.

That's because we decided to not rely on the media-type.

>>>   There are very few cases where there are
>>> differences, POST only.
>>
>>
>> I would argue it's not only POST:
>>
>> * GET-on-LDPC and GET-on-LDPR don't have (yet) the same exact
>>    semantics (see ISSUE-90).
>
> I've read that issue and not entirely clear to me the difference.
>
>>
>>
>> * PUT-on-LDPC has overridden semantics regarding the membership
>>    triples.
>
> Well, if it were me we'd save energy talking about PUT-on-LDPC here and
> just do PATCH.  So fixing these PUT cases may be necessary but in time, may
> not be.

I don't think PATCH will change anything.

>> I don't know how people are planning to implement that in
>> practice. For what I'm concerned, there is a disjunction between the
>> LDPR and LDPC logics, and I suspect that most of the implementations
>> will reflect that. I may be wrong of course.
>>
>>
>>>      My proposal is to say that the interaction model is directly (and
>>>      solely) derived from the "type" Link header, having one for the LDPR
>>>      and one for the LDPC. This is aligned with the previous proposal of
>>>      not defining a new media type but to extend the existing RDF ones
>>>      with the rel='type' Link header.
>>>
>>>      For an LDPR (and ideally for Binary if it also were an LDPR):
>>>      Link: <http://www.w3.org/ns/ldp#Resource>; rel="type"
>>>
>>>      For an LDPC:
>>>      Link: <http://www.w3.org/ns/ldp#Container>; rel="type"
>>>
>>>      Now, I can copy the content of an LDPC (eg. for backup purposes)
>>>      into a new LDPR, without inheriting the LDPC interactions.
>>>
>>>
>>> Please elaborate on this motivating use case "backup purposes".  What
>>> LDPC interactions cause problems? The only "real" difference would be
>>> POST behavior...right?  If if is a backup, wouldn't the ACL be set to
>>> prohibit writing to it, so POST, PUT, PATCH wouldn't be supported.
>>
>>
>> It has nothing to do with ACLs.
>>
>> Here is a full example.
>>
>> [[
>> $ curl -i http://example.org/container1/
>> ...
>> Content-Type: text/turtle; charset=UTF-8
>>
>> Link: <http://www.w3.org/ns/ldp#Resource>; rel="type"
>> ...
>> <>
>>     a ldp:Container;
>>     ldp:containerResource <> ;
>>     ldp:containsRelation rdfs:member;
>>     ldp:insertedContentRelation ldp:MemberSubject;
>>     dcterms:title "A very simple container";
>>     rdfs:member <member1>, <member2>, <member3>.
>> ]]
>>
>> Now, I want to save that content somewhere else.
>>
>> [[
>> $ curl -X POST -i \
>>   -H 'Content-Type: text/turtle; utf-8' \
>>   -H 'Slug: container1/' \
>>   -d @./container1.ttl \
>>   http://betehess.example.org/myContainer/
>> ]]
>>
>> In this case, I didn't want `myContainer` to create a real Container,
>> just a plain regular LDPR-RDF, which just happens to have { <> a
>> ldp:Container } in it.
>
> So this assumes that your implementation must create something a bit heavy
> weight to deal with LDPCs.  Ok, I understand the use case better now and
> how it doesn't deal with ACLs.  Though I could see a number of
> implementations only creating transient objects of lighter weight to deal
> with certain LDPC requests (for example if impl knew it was always going to
> be a read-only container, it wouldn't have to worry about as much).

I fail to see how this is heavy-weight. The action dispatching (is it
a LDPC or LDPR?) happens before parsing the body.

>> With my proposal, you would do the following to create an LDPC:
>>
>> [[
>> $ curl -X POST -i \
>>   -H 'Content-Type: text/turtle; utf-8' \
>>   -H 'Link: <http://www.w3.org/ns/ldp#SimpleContainer>; rel="type"' \
>>   -H 'Slug: container1/' \
>>   -d @./container1.ttl http://betehess.example.org/myContainer/
>> ]]
>>
>> And you can see here why the indirection of the DirectContainer (and
>> of course the IndirectContainer as well) is problematic.
>
> So you are only proposing this request header on POST (create) of a LDPC?
>   Ok, that would be good to understand.

I'm proposing it for *all* interactions (GET/POST/PUT), just like a
media-type. Both for the LDPR *and* the LDPC.

>  I would assume we should prohibit
> giving an LDPR LDPC semantics?

I'm fine with forbidding this scenario. One can always delete the
resource before recreating it with another flavour.

With my proposal, adding { <> a ldp:Container } to an existing LDPR is
very-well specified: it just adds the triple and does not change the
nature of the resource.

>>> I'm not sure this added complexity really fixes anything.  A client
>>> would request LDPR semantics on a LDPC, say for a POST request, though a
>>> server could reject it.  How does this help the client out?
>>>
>>>
>>>      Also, creating an LDPC is now easy to define (and implement): you
>>>      POST a document *with* the corresponding Link header (otherwise,
>>>      it's an LDPR, or a Binary).
>>>
>>> Creating an LDPC was easy before, you just POST the LDPC representation.
>>>    Would you expect the Link header to possibly be different from the
>>> rdf:type in the LDPR?
>>
>>
>> The rdf:type would be used for validation only, just like the rest of
>> the body. If the nature of a POSTed resource was defined by what's in
>> the body, that would be a precedent in the REST world.
>
> In the REST world can you create a "service" and then in that a "shopping
> cart service"?

You will have to define that better for me to be able to answer :-)

>  How do those things come into existence?

There is usually a collection-like resource. It's typically media-type
driven.

>  I would assume in
> a REST world you'd POST a descriptor to "create" those services.  The
> behavior of those services would be based on the descriptors of them.

I don't know what a "descriptor" is. We would just follow the
semantics associated with the media-types being involved.

>>>   Would it be expected that the server maintain the
>>> value of the link header as the preferred default semantics of the
>>> resource, instead of derived from rdf:type?
>>
>>
>> Totally. In our case, the type-Link header (plus the real
>> Content-Type) behave like a new media type.
>
> So this has the drawback that it can never change.  Or do you expect a PUT
> on the LDPC with Link: <http://w3.org/ns/ldp#SimpleContainer> rel='type'
> (or some other means) to modify the behavior originally set by the client?
>   I don't think this model gets us into any better of a place.

That's related to a question you asked above. If a server knows how to
do that then why not. We can also request the client to delete the
resource first. I don't have a strong preference at the moment.

>>> An advantage I see with this Link header is that I server wouldn't have
>>> to parse the request document to locate the rdf:type, unless it wanted
>>> to do some additional validation.
>>
>>
>> I have made this argument so many times :-)
>>
>> Note that the "additional validation" has nothing to do with LDP, as
>> LDP is only about the interactions (well, almost :-).
>
> I'm not sure exactly what you mean but some applications may want to
> provide additional diagnostics when there are potential conflicts in their
> headers and data, that is what I was talking about.  Such as: "Hmmm...the
> client said do this request as a LDPC on a LDPR, that seems a little odd".

There is no conflict.

`Content-Type: text/turtle` just means: this is Turtle, trigger the
right parser. A client/server can decide if it is valid by actually
parsing it. There is no other associated semantics to it, especially
no interaction.

`Link: <http://www.w3.org/ns/ldp#Resource>; rel="type"` means that the
resource is an LDPR and that it supports the associated semantics (the
interactions defined by the specification). At this point, it's not a
problem to say that an LDPR can be an RDF resource or a Binary one,
you'd know just by looking at the media-type.

`Link: <http://www.w3.org/ns/ldp#Container>; rel="type"` means that
the resource is an LDPSimpleContainer. To be valid, the spec enforces
the representation for an LDPR to be some RDF, with some additional
triples (eg. RDF type, membershipXXX triples, etc.).

About the "potential conflicts in their headers and data". I don't
think there is any problem. RDF does not mean that every triple you
see is true, or that it should drive the interaction. It's actually
left open to Interpretation (the I function in RDF Semantics). The
conflict you're talking about is just another notion of truthfulness.

>>> If you want to "turn off" membership triple creation when a new resource
>>> is created via POST to LDPC, it would be good to understand if that is
>>> what this issue is trying to accomplish as it seems like it is.  If so
>>> or not, then it would help me understand it better.
>>
>>
>> It's not that much about the membership triple creation. It's more
>> about the nature of the resource, as the resource would not be an LDPC
>> to begin with.
>
> This doesn't really answer the question, I believe you answered it before
> by confirming the POST behavior, saying there might be something on GET
> (ISSUE-90) and PUT on LDPCs.
>
> I'm curious how common this "archive" case is and it could just be up to a
> few implementations that need a hint to just "archive" and not treat
> resource with an additional semantics.  For a number of LD applications I
> have seen, they desire a consistent way to do archiving but more of a verb
> (like DELETE) or resource state (like archived=true, or archivedDate=)

I usually try to convince people with an example first, but I'm much
more interested in invariants. And "archiving" is just one example. My
point is the following: it's not because you've seen { <foo> a
ldp:Container } that <foo> really is a ldp:Container supporting all
the expected interactions.

There was a time when the XML community was struggling with the same
problems, using application/xml as a media-type for everything and
deriving the interactions from the namespace of the root (but what
does it mean when there are several of them?). It took some time, but
it looks like the Web API community has learned from it. See the
popularity of buzzwords like hypermedia or HATEOAS.

> Thanks for taking the time to elaborate the details of your issue and use
> case.

Thank _you_ for the careful review.

Alexandre.

>
> - Steve Speicher
>
>>
>> Alexandre.
>>
>>> - Steve Speicher
>>>
>>>
>>>      Alexandre.
>>>
>>>      [1]
> https://dvcs.w3.org/hg/ldpwg/raw-file/default/ldp.html#ldpr-4_2_10
>>>
>

Received on Wednesday, 27 November 2013 16:12:03 UTC