- From: Thomas Hoppe <thomas.hoppe@n-fuse.de>
- Date: Fri, 17 Apr 2015 20:35:11 +0200
- To: Dietrich Schulten <ds@escalon.de>
- CC: Hydra <public-hydra@w3.org>
Hi Dietrich, On 04/14/2015 07:44 PM, Dietrich Schulten wrote: > Hi Thomas, > > Comments inline. > Am 14.04.2015 15:29 schrieb Thomas Hoppe <thomas.hoppe@n-fuse.de>: >> Hi Dietrich, >> >> please see my comments below. >> >> On 04/13/2015 09:39 PM, Dietrich Schulten wrote: >>> Hi Thomas, >>> >>> I see this as a deliberate constraint which comes from the fact that you need to say what it is you are operating on. Either it is the current resource, or a related resource. For the current resource, its @id seems the obvious choice. >> If it is as you say (which is of course a sane default and what one >> would expect), I would like to see this to be defined in the spec. >> I will create and issue after the discussion here on the list. > Yes, I remember that I was also wondering about the operation url, then realized it is restricted to the @id of the resource which supports the operation and asked myself if this will always work. > > Design-wise this makes sense. We want to describe a method which can be executed on either the current resource or a related resource. Yes. I have added issue #100 asking for a description of this mechanics in the spec. >> Nicely, this also works for nested JSON-LD structures like this: >> >>> If it is a related resource, you need a property which expresses the relationship, and in that case the related item again has an @id, which is of course different from the @id of the current resource. I couldn't find an example where a PUT or DELETE would not work under this constraint. >>> >>> For collections you want to POST to, the situation is different. Here we have the new collection design, where the @id identifies the collection and the hydra:collection property expresses an all-purpose relationship with the current resource. That allows to use pretty much everything as a POST target, and the property in the manages block can be an arc between the collection items and a thing which is not the current resource; maybe even a thing which doesn't exist yet. I have found that this gives me the freedom I needed so far. >> Isn't the collection just an example for the case you mentioned above >> ("related resource") in which the relation happens to be the >> hydra:collection? >> See this example derived from the restbucks API: >> >> { >> "@context": { >> "hydra": "http://www.w3.org/ns/hydra/core#" >> }, >> "@id": "http://example.com/items", >> "name": "Latte Macchiato", >> "hydra:collection": [ >> { >> "@type": "hydra:Collection", >> "@id": "http://example.com/orders" >> }, >> "hydra:operation": { >> "hydra:method": "POST", >> ... >> } >> } >> ] >> } > That was exactly the construct I had in mind :-) > > The hydra:collection is indeed just a special case. First the client looks up related hydra:collection members. The thing is, there could be multiple related collections, so in order to find the right one the client must look at the manages block. > > In that regard hydra:collection is not unlike a _links member where the client has to look at the rels of the enclosed links to find the right one. > >> I see the collection as the relation having an @id which differs from >> the current resource IRI >> and with the "rules" you have described above for the related resource, >> you can nicely resolve >> http://example.com/orders as the target for the operation. >>> Do you have an example which cannot be expressed within the constraints of the current design? >> Yes, I still think we have a gap. >> What if I wanted to do this this: >> >> { >> "@context": "http://www.w3.org/ns/hydra/context.jsonld", >> "@id": "/issues/", >> "title": "Issues collection", >> "operation": [ >> { >> "@type": "xyz:DeleteResourceRecursivelyOperation", >> "label": "Delete all issues recursively", >> "method": "DELETE", >> "target": "/issues/?recursive" >> } >> ] >> } >> >> The resulting DELETE request would require a query parameter to be in >> the IRI (maybe even IRI templates might be sensible here). >> If it would be just a GET based affordance, we could model this with a >> hydra:Link or just with the means of JSON-LD's >> {"@type": "@id"} idiom in the context, but in this case: >> 1.) I want to tell the client to construct a non-GET-request >> 2.) I explicitly want to leverage a typed operation like in this example >> xyz:DeleteResourceRecursivelyOperation which the client might happen to know >> >> This case might appear a bit artificial but just let's assume one needs >> to describe an >> existing API which happens to function like this. > I see your point, legacy APIs. However, the resource > > /issues/?recursive > > is a different resource than the > > /issues > > resource. The former is not the /issues resource, only with a parameter to the delete method. It is a different resource. sure. > In this case we can use hydra:collection to express that: > > { > "@context": "http://www.w3.org/ns/hydra/context.jsonld", > "@id": "/issues/", > "title": "Issues collection", > "collection": [ > { > "@type": "hydra:Collection", > "@id": " /issues/?recursive", > "operation": [ > { > "@type": "xyz:DeleteResourceRecursivelyOperation", > "label": "Delete all issues recursively", > "method": "DELETE" > } > ] > } > > You will probably want a manages block with an xyz:issuesRecursive property, too, so you can identify just what you are going to erase in a delete cascade. > I think the hydra operation constraint holds, what do you think? that is a solution, yes and the xyz:issuesRecursive's value would then point to the collection. Ok, so I cannot say, it's impossible to model with what we have but with a target property it would at least be possible to express it less verbose and that's why I think it might be sensible to have this construct. A drawback would then of course be that you can model things in multiple ways. Apart from that I cannot think of anything else that cannot be modeled with what we have. Greets, Thomas > > Best regards, > Dietrich
Received on Friday, 17 April 2015 18:35:41 UTC