Re: Target URL of Operations

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.

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

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?

Best regards,
Dietrich

Received on Tuesday, 14 April 2015 17:44:44 UTC