Re: Interpretation of POST operation given large relationship collections

On Oct 14, 2014, at 5:34 AM, John Walker <john.walker@semaku.com> wrote:

> Hi Gregg
> 
> > On October 12, 2014 at 9:36 PM Gregg Kellogg <gregg@greggkellogg.net> wrote: 
> > 
> > 
> > The primary (only?) way of updating a Hydra resource is through an operation using the POST method. This would seem to have some small conflict with the use of hydra:Collection to manage resources having a potentially large number of relationships. 
> > 
> > Imagine an entity such as a Movie, with a large number of reviews. It might be reasonable to manage the reviews through a paged collection, due to the potential for a very large number of such reviews:    
> > 
> > <GoneGirl> a schema:Move; 
> > schema:name "Gone Girl"; 
> > hydra:hasCollection <GoneGirl/reviews> . 
> > <GoneGirl/reviews> a schema:PagedCollection; 
> > hydra:manages [hydra:subject <GoneGirl>; hydra:property schema:review ] 
> >
>  
> I was attempting to work my way through an example like this using SKOS instead on Schema.org [1].
> Following best SemWeb practices I had modeled the entity and the information about it as separate resources, in your example that might be:
>  
> <GoneGirl> a hydra:Resource ;
>   foaf:primaryTopic <GoneGirl#id> .
> <GoneGirl#id> a schema:Movie ;
>   schem:name "Gone Girl" ;
>   hydra:collection <GoneGirl/reviews> .
> <GoneGirl/reviews> a hydra:PagedCollection ;
>   hydra:manages [hydra:subject <GoneGirl#id> ; hydra:property schema:review ] .
>  
> > schema:Movie would be extended as a hydra:Class, with schema:review as a supportedProperty. schema:review would also be a hydra:Link. Using the existing SupportedProperty, this might look like the following: 
> > 
> > schema:Movie a hydra:Class; 
> > hydra:supportedProperty [ 
> > a hydra:SupportedProperty; 
> > hydra:property schema:review; 
> > hydra:readonly false; 
> > hydra:writeonly false 
> > ]; 
> > hydra:supportedOperation [ 
> > a hydra:Operation; 
> > hydra:method "POST"; 
> > hydra:expects schema:Movie; 
> > hydra:returns schema:Movie 
> > ] . 
> > 
> > A client has know way to know that schema:review is managed by a collection without retrieving the resource (fine). From an RDF perspective, the schema:review triples all have the same subject <GoneGirl> pointing to different reviews. When I retrieve the resource, I don't get all these reviews, even if I indirect through the paged collection, maintaining all triples referencing the review could take a fair amount of space. 
> > 
> > The point of the question is, what is the interpretation of POST? Does it replace all the triples having the same subject (presumably including referenced/referenced resources having a BNode subject including those managed through a collection? Does it exclude resources managed by a collection? What about if there is a propertyPath specifying the subject resource using a reverse relationship? 
> >
>  
> 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 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.

> 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.

> > 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.

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 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'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.
>  
> _: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.

> 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.

> 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.

> 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.

Gregg

> > Thoughts? 
> > 
> > Gregg Kellogg 
> > gregg@greggkellogg.net 
> > 
> >
>  
> John
>  
> [1] https://github.com/jaw111/skos-api

Received on Tuesday, 14 October 2014 18:32:56 UTC