RE: Interpretation of POST operation given large relationship collections

On Tuesday, October 14, 2014 10:08 PM, John Walker wrote:
> On Tuesday, October 14, 2014 8:32 PM, Gregg Kellogg wrote: 
> > On Oct 14, 2014, at 5:34 AM, John Walker wrote:
> > > I'd expect that a POST on <GoneGirl> would append any triples in the
> > > request body to the <GoneGirl> resource, but perhaps a PUT would
> > > better apply here to replace the resource with the request body?
> > 
> > I guess the spec needs to be clear about this. From normal REST
> > practices a PUT would replace a resource representation, a PATCH might
> > amend portions of it, and a POST would create a new one. My assumption

The HTTP spec [1] says that

   The PUT method requests that the state of the target resource be
   created or replaced with the state defined by the representation
   enclosed in the request message payload.

and that

   The POST method requests that the target resource process the
   representation enclosed in the request according to the resource's
   own specific semantics.

which means POSTs semantics are defined by the target resource. That's exactly the reason why it is so important to properly type the operation. Otherwise a client has no clue what happens if it POSTs something.


> > would be that POSTing to an existing resource would return a 409
> > Conflict, as a POST is typically considered a Create operation, and
> > attempting to create a previously existing resource could be
> > considered an error.

That's neither how POST is define nor how it is normally used. Think of form submissions on websites, resource creation on containers/collections etc.


> The append behaviour was based on how POST works in SPARQL 1.1 GSP,
> but that doesn't really fit in this context.

Right

 
> So here we say it would only ever make sense to POST to a
> hydra:Collection resource right? Or is there any use case where we
> wouldn't pull the schema:Review instances out to separate resources
> and POSTing a review to the movie resource would embed the review in
> the representation of the schema:Movie? The latter doesn't sound like
> a good practice to me if I want to be able to DELETE the review, but
> that *could* also be achieved with a PATCH if the review is embedded.

Exactly.. a PUT would work as well (and wouldn't require a different media type).



> > > If I wanted to add a new review, would I POST a representation of that
> > > review to the <GoneGirl> or <GoneGirl/reviews> resource? Personally
> > > would expect the latter in the case where a hydra:Collection is used.
> > 
> > I think the later too, if the POST also creates the Review. Posting to
> > the collection implicitly associates the review with the movie and
> > adds it to the collection.

+1


> > > > Perhaps marking the property readonly: true would give sufficient
> > > > information that the property can't be managed this way, and
> > > > operations must be performed on the associated collection or using a
> > > > LINK/UNLINK method on the resource? Otherwise, requiring the client
> > > > to post all such relationships is unfeasible, and we have no other
> > > > communication mechanism to say that they should/must be excluded
> > > > from the resource representation when doing a POST.
> > >  
> > > In case where a hydra:Collection is used to manage the schema:Review
> > > list, I'd expect the schema:review property to not even be present in
> > > the <GoneGirl> resource.

Well, this brings us back to our "Schema.org properties having a collection as value and hydra:Collection" discussion. With Schema.org, both options are OK.


> > Maybe, but if you were to simply look at vocabulary information you
> > would see that schema:review is a property of schema:Movie. From a

Strictly speaking you wouldn't see that. You would just see that schema:review's domain *includes* CreativeWork, Offer, Organization, Place, and Product... but that is nitpicking.


> > triples perspective, it is as well, as the collection manages Movie
> > review Review triples, but it's not in the API, so it might just be
> > not present, or marked readaable/writable=false. The later indicates
> > that providing such a triple as part of the create/update operation on
> > Movie is explicitly excluded, while the former doesn't really may any
> > claim.
> 
> I think this is partly where I am getting lost a bit. From a triples
> perspective I am quite happy if the triples with the same subject URI
> are actually spread over several dereferenceable Hydra resources. That
> might not be handy for a consumer, but as long as those resource
> reference each other (with rdfs:seeAlso for example) then I can follow
> my nose.

Right. Currently those triples would be in the (paged) collection which is a different resource but referenced from the movie.


> Another area that is not 100% clear to me is what exactly I would get
> when I dereference the collection. Can imagine bare minimum would be:
> 
>   <GoneGirl/reviews> a hydra:PagedCollection ;
>     hydra:manages [
>          hydra:subject <GoneGirl> ;
>          hydra:property schema:review
>     ] ;
>     hydra:member <GoneGirl/reviews/review1> ,
>                  <GoneGirl/reviews/review2> ,
>                  <GoneGirl/reviews/review3> .
> 
> Or would I also include the following triples in the response:
> 
>   <GoneGirl> schema:review <GoneGirl/reviews/review1> ,
>                            <GoneGirl/reviews/review2> ,
>                            <GoneGirl/reviews/review3> .
> 
> I guess I could also embed the reviews themselves in the response...

All three options are fine. The Movie -review-> Review triples need to be somewhere though.


> > > I'm wondering what I need to POST to the <GoneGirl/reviews> resource. 
> > > As my new review has no identity yet, it'd be a blank node I assume.

Correct.


> > > _:b0 a schema:Review ; 
> > >   schema:itemReviewed <GoneGirl> ; # or <GoneGirl#id> 
> > >   schema:reviewBody "What a great film" ; 
> > >   schema:reviewRating 5 .
> > 
> > My thinking too. The issue is with embedded resources also using blank
> > nodes known which resource represents the subject of the POST. In my
> > view, it is the subject who's type matches a range of the property
> > associated with the collection.

That's the approach I currently use in my PHP implementation. It works quite well. The LDP WG decided to use relative URLs instead of blank nodes which has its pros and cons (parsing to RDF without base is typically not possible as RDF requires absolute IRIs).


> Makes sense, could also POST multiple reviews with this approach.
> What about reviews of reviews ;P

You would need to do this in two steps. The first POST creates a review and a collection to which you can then POST the reviews of that review.


> > > Would I also need to explicitly include the triple linking the movie
> > > to the review:
> > >   
> > >    <GoneGirl> schema:review _:b0 . 
> > >    # <GoneGirl#id> schema:review _:b0 .
> > 
> > Not necessary, I think, as it is implicit in posting to the collection
> > managing that relationship.

I agree. The collection explicitly states that it manages a specific subject-predicate pair so it will take care of that.


> > > And/or the triple stating the review is a member of the collection:
> > >   
> > >    <GoneGirl/reviews> hydra:member _:b0 . 
> > >   
> > > Or is it reasonable to assume the server will add these?
> > 
> > I believe it is, but the spec should be clear on this.

Given that we eliminated all predefined operation types it will be difficult to specify that. The way to do it would be to define a AddToCollectionOperation and describe its behavior. The definitions of actions in Schema.org (e.g. http://schema.org/AddAction) are unfortunately very vague at this point. If this turns out to be a problem, we could create separate vocabularies precisely defining such operations.


> > > In the case of using LINK/UNLINK this would only be possible if the
> > > schema:Review already had an identitiy URI, so assume the client would
> > > have already had to POST it to some other generic <allReviews>
> > > collection.
> > 
> > Yes, you might imagine that a review is posted to a Movie, but a
> > subsequent operation might want to make it a review of the actor's as
> > well (better NewsArticle being about multiple things). This is where I
> > was considering LINK/UNLINK.
> > 
> > > And I'm not sure how I would use LINK/UNLINK in the case that the
> > > movie used the hash URI pattern <GoneGirl#id>?
> > 
> > The hash URI can certainly be part of the link href. It may be up to
> > server interpretation to associate the operation with the Movie vs.
> > the Resource. It also may be that LINK/UNLINK operations aren't
> > appropriate when using hash URIs. They could also be performed using
> > something like a POST with a schema:AddAction or schema:DeleteAction
> > on the collection; I find the minimalism of LINK/UNLINK verbs
> > appealing, even though they're not quite standard yet.
>
> Agree on the minimalism (UN)LINK. With hash URIs it might also be
> worth to consider if/how that would work with fragment identifiers in
> HTML documents. I guess a PATCH could be used for this also.

LINK/UNLINK work fine with fragment identifiers. I just filed an issue [2] to include such an example in the LINK/UNLINK spec:

   LINK /alice HTTP/1.1
   Host: example.org
   Link: <http://example.com/bob#me>; rel="http://schema.org/knows"; anchor="#me"

Which effectively creates this triple

  <http://example.org/alice#me> <http://schema.org/knows> <http://example.com/bob#me> .


Cheers,
Markus


[1] http://tools.ietf.org/html/rfc7231#section-4.3
[2] https://github.com/jasnell/specs/issues/4 



--
Markus Lanthaler
@markuslanthaler

Received on Wednesday, 15 October 2014 10:42:32 UTC