Re: How to GET a cup of coffee - Restbucks with Hydra

> On Mar 11, 2015, at 2:00 AM, Dietrich Schulten <ds@escalon.de> wrote:
> 
> Hi Gregg,
> 
> thank you for looking into this.
> 
> 
> 
> On March 8, 2015 9:10:06 PM Gregg Kellogg <gregg@greggkellogg.net> wrote:
> 
>> > On Mar 8, 2015, at 11:08 AM, Dietrich Schulten <ds@escalon.de> wrote:
>> >
> 
>> 
>> This doesn't really say what you want. IIRC, there is a hydra:object property that can be put in the manages block to imply that the collection members are subjects of that relationship rather than objects.
> 
> ...
> 
>> However, this doesn't seem right. The result of an operation would be something like the following:
>> 
>> {
>>  "@type": "Order",
>>  "productId": "latte-1"
>> }
> 
> No, the response to the POST would be an Order with an orderedItem.
> 
>> 
>> In which case, the this would be related using the orderedItem property to the entity associated with the collection (a store):
>> 
>> {
>>  "@type": "Order",
>>  "productId": "latte-1",
>>  "orderedItem": "http://example.com/store"
>> }
>> 
> 
> I do not understand why the store becomes the object of orderedItem here, there was no triple which stated that. Is there some general assumption at work which relates the previous response (which was a Store) to the response of the POST (the Order)?

I didn't look closely at http://schema.org/orderedItem to see the range as Order rather than the Domain, in which case you'd probably want the following:

{ 
  "@context": ["http://schema.org", "http://www.w3.org/ns/hydra/core", {
    "@vocab": "http://schema.org/",
    "hydra:object": {"@type": "@id"},     
    "hydra:property": {"@type": "@vocab"}
  }],
  "name": "Latte Macchiato",
  "hydra:collection": [
    {   
      "@type": "hydra:Collection",
      "@id": "http://example.com/orders",
      "hydra:manages": {
        "hydra:property": "orderedItem",
        "hydra:object": "http://example.com/latte-1"
      },
      "hydra:operation": {
        "hydra:method": "POST",
        "hydra:expects": {
          "hydra:supportedProperty": [
            {
              "@type": "PropertyValueSpecification",
              "hydra:property": "productID",
              "hydra:required": true,
              "defaultValue": "latte-1",
              "readOnlyValue": true
            }
          ]
        }
      }
    }
  ]
}

It seems the the result of this operation should add a product to an order, rather than a person (referenced via hydra:object) and result in a relationship from the Order to the Product rather than a Customer to the Order:

{
  "@type": "Order",
  "orderedItem": {
    "@type": "Product",
    "@id": "latte-1"
  },
  "productID": "latte-1"
}

This seems to make the "productID" property (not defined in schema.org anyway) redundant?

>> I would think this would, in fact be a forward relationship from customer to their order:
>> 
>> {
>>  "@type": "Person",
>>  "orderedItem": {
>>    "@type": "Order",
>>    "productId": "latte-1"
>>  }
>> }
> 
> The restbucks service (in Webbers blogpost) does not associate the order to the customer. Which also makes sense, if you think about it - there are many cases where the customer can be anonymous, also on the web.
> 
>> 
>> So, just using the orderedItem as the hydra:property relationship is probably what you intend. Interestingly, due to the way @reverse works, this is, in fact, what you are saying, because @reverse doesn't have the intended effect when using as a value rather than a property.
> 
> Wow, surprise! Is that a bug in the playground, a gap in the json-ld spec or is it really intended that a reverse property becomes the unreverted URI when used as an attribute value with @type:@vocab?

No, that's intended behavior. @reverse operates on properties, not values; in this case, you're using it as a value. Otherwise, it would imply an even more complex semantic relationship, which is outside the scope of JSON-LD.

> Actually that helps, we could then safely @index the collection items by the property URIs.
> 
>> So, using hydra:subject instead of hydra:object in the manages block is probably the right thing.
>> ...
>> "hydra:subject": "http://example.com/customer"
> 
> 
> In Webber's restbucks the orders are at an /orders resource below the store. So what I want is the store as a subject, if I *have* to name the subject. And I can drop the @reverse on orderedItem in the Wiki.
> 
> I'll adjust the Wiki accordingly.
> 
> More of a background question:
> 
> The mechanics of the manages block seems to be that the collection members are either subject or object of the collection triples. Which of both the members are, depends on the presence of subject or object. If there is a subject, the members are the object and vice versa.

Correct.

> The question is, what exactly do we say if the manages block only contains a property, but no object or subject? I would assume we say that the collection manages the property, but we leave it undefined if the items are subject or object. Maybe it would be preferable if the managed block would not make the members a subject or object by omission, but by asserting exactly what they are.

From my interpretation, without giving hydra:subject, you leave the relationships undefined. However, you might imagine some inference rules such as the following:

SSS hydra:collection CCC .
CCC hydra:manages MMM .
implies
MMM hydra:subject SSS .

But, it should only do so if MMM has no hydra:object, so it's more complicated than that. Best to be explicit. Moreover, in my use of collections, I ensure that the actual described triples are manifest in the collection, so if you had the following:

<> a hydra:Collection;
  hydra:manages [hydra:subject <SSS>; hydra:property <PPP>];
  hydra:member <OOO> .

I would also add

<SSS> <PPP> <OOO> .

In JSON-LD, it might look like the following:

{ 
  "@context": ["http://schema.org", "http://www.w3.org/ns/hydra/core", {
    "@vocab": "http://schema.org/",
    "hydra:object": {"@type": "@id"},     
    "hydra:property": {"@type": "@vocab"}
  }],
  "name": "Latte Macchiato",
  "hydra:collection": [
    {   
      "@type": "hydra:Collection",
      "@id": "http://example.com/orders",
      "hydra:manages": {
        "hydra:property": "orderedItem",
        "hydra:object": "http://example.com/latte-1"
      },
      "hydra:member": [{
        "@id": "... new-order",
        "orderedItem": "http://example.com/latte-1"
      }],
      "hydra:operation": {...}
    }
  ]
}

However, I don't believe Hydra creates any such requirement.

Gregg

> Best regards,
> Dietrich
> 
> 
> 
> 
> 

Received on Wednesday, 11 March 2015 21:44:47 UTC