- 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