Re: In-place hydra:Link

Hi Dietrich,

More comments inline

October 7 2014 6:47 PM, "Dietrich Schulten" <ds@escalon.de> wrote: 
> Thanks to both of you!
> 
> Comments inline.
> 
>> Markus Lanthaler <markus.lanthaler@gmx.net> hat am 7. Oktober 2014 um 10:39
>> geschrieben: 
>> 
>> On 7 Okt 2014 at 09:27, tomasz@t-code.pl wrote:
> 
>>> October 7 2014 9:16 AM, "Dietrich Schulten" wrote:
> 
>>>> is it possible to express that an attribute is a hydra:Link inside a 
>>>> json object, without external context, either by saying so near a 
>>>> jsonld IRI like this: 
>> 
>> I think we should first clarify what a context is and what a (vocabulary)
>> definition is.
>> A JSON-LD context defines a mapping from meaningless string tokens (we call
>> them terms) such as JSON property names to IRIs. The context may also be
>> used to language tag string values or to type them. A vocabulary definition
>> describes the IRIs (resources) that are used within a JSON-LD document or
>> context. To make this a bit more concrete, a context that maps the term
>> "comments" to "http://api.example.com/vocab#comment" would look as follows: 
>> 
>> { 
>> "@context": { 
>> "comments": "http://api.example.com/vocab#comment" 
>> } 
>> } 
>> 
>> This tells a client only what the IRI corresponding to the "comments"
>> property in the following document is: 
>> 
>> { 
>> "@context": ... 
>> "comments": [ 
>> { "@id": "/comments/1", "title": "A comment" } 
>> ] 
>> } 
>> 
>> But if the client doesn't understand that IRI
>> (http://api.example.com/vocab#comment) yet, it has too little information
>> to process it. Thus, you describe it in a machine-processable manner.
>> Following Linked Data principles (use deferenceable URLs to name things),
>> you would put that description in the document
>> at http://api.example.com/vocab: 
>> 
>> { 
>> "@context": "http://www.w3.org/ns/hydra/core", 
>> "@id": "http://api.example.com/vocab#comment", 
>> "@type": "hydra:Link", 
>> ... 
>> }
> 
> Ok. Is the json above a vocabulary json, then? 
> What makes a jsonld object a vocab? Do we have documentation somewhere
> which describes how to write a vocab with json-ld?
>

I'm not sure I understand. There is no difference between json-ld (rdf in fact) resource representation. They are just resources.
 
>
> In most cases, a vocabulary defines more than one item, so is this is a
> special case of a single item vocab? Once I have more than one item, how
> would I write it?
>

With JSON-LD you could create an array to simply describe multiple resources in one document. However you could also use more complex RDF or OWL constructs to structure your ApiDocumentation. Have a look at the http://www.markus-lanthaler.com/hydra/api-demo/vocab#. At the root you have the ApiDocumentation and then classes, operations and properties in a tree structure. However if you flatten [1] that document with a null context you would get a flat array of separated objects. This way it may be easier to access individual resources by identifier. 

> 
> Is it mandatory to write my own vocabulary in order to specify that an
> attribute in my responses is meant to be dereferenced? My vocabulary should
> then be of @type ApiDocumentation, I guess.
>

I think you don't need to define your own vocabulary for properties and type. I think that in the ApiDocumentation you could write (excerpt)

{
  "@id": "schema:Person",
  "hydra:supportedProperty": {
    "hydra:property": { 
      "@id": "schema:knows",   
      "@type": "hydra:Link"
    },
    "hydra:title": "knows",
    "hydra:description": "The user's acquaintances",
    "hydra:readonly": false,
    "hydra:writeonly": false
  }
}

This way you can reuse other vocabularies and declare them to be dereferencable links. At the same time you don't hijack the schema terms, becasue your extensions are defined in the ApiDocumentation, which is only exposed by the HTTP header. If you included the above in you representation you would inadvertently extend a vocabulary you don't own, which is not desirable.
 
>
> That would mean that the documentation for an api cannot be inlined, it
> must be downloaded (and generated) separately from the responses. Hm.
>

That is true and in fact could be necessary (see above). Why is that a problem? It's not like you have any duplication here.
 
>
>> Now, a client that doesn't understand the IRI is able to look it up (since
>> it is actually a URL). If it did so, it would find out that this IRI/URL
>> represent a hydra:Link. So, the client would know that "comments" is
>> actually a link. 
>> 
>> As Tom already said, using this "methodology", you would have to
>> dereference each IRI you encounter without knowing beforehand whether it is
>> worth it. Thus, in most cases it is beneficial to define an
>> ApiDocumentation (a single document) which describe those things and
>> requires just a single HTTP request.
> 
> I guess it depends on the use case if you see that as beneficial ;)
> 
> Now when I encounter an attribute I have to dereference the vocab to see if
> it is a link and then go and dereference the original link. Somehow I
> really wish I could simply tell the client "this is a link you want to
> dereference" inside the response.
>

The problem is what I outlined above. If you want to reuse some vocabulary like schema.org of FoaF you would publicly expose statements about external terms. And that information is only ever intended to be used locally with you API. There is no way to restrict that. In other ways if you say that "in this response the schema:knows is a dereferencable link" it means that any crawler that finds you data would take that as universal a fact. These agents may not be out there yet, however that's how it works.
 
>
> My idea of "follow your nose" in an api was that I can follow links when I
> encounter them, without needing a map (i.e. ApiDocumentation) beforehand.
>

Right but how do you distinguish between a schema:image (whose object goes to an <img /> tag) and a schema:knows (which you would want to follow)? For an automated client they are equivalent. There is no way to tell which is intended for either usage. 

And it's even worse if they are from a share vocabulary. You couldn't dereference the properties to inspect their descritpions, because they are not defined as hydra terms by their owners. Hence you need to map them in you ApiDocumentation.
 
>
> "Map beforehand" has these problems: it is difficult to generate, it
> duplicates the api structure and can get outdated (server must send
> must-revalidate and last-modified so that clients can transparently use
> their cached map), it makes client implementations substantially more
> complicated.
> 
> Is it not feasible to do what I want with json-ld, or does hydra simply not
> provide for that possibility yet?
> 
>>>> { 
>>>> "@context" : { 
>>>> "@vocab" : "http://schema.org", 
>>>> } 
>>>> "@type": "Event", 
>>>> "name": "Walk off the Earth - REVO tour", 
>>>> "offers" : { 
>>>> "@id": "http://api.example.com/event/123/offers", 
>>>> "?": <-- say that this is to be dereferenced as hydra:Link 
>> 
>> Almost. You could use hydra:Resource in this case to achieve what you want.
>> A hydra:Link is simply a property, whose value is a hydra:Resource, i.e., a
>> dereferenceable Web resource. If you would like to define the "offers"
>> property itself, you would have to do that separately as Tom outlines
>> further down. But in this case, it isn't necessary IMO.
> 
> Interesting. How would that look like then?
> 
>> Yep, that's fine.. but please keep in mind that the context from in the
>> first object doesn't apply to the second object... you would have to repeat
>> it or structure your document slightly differently: 
>> 
>> { 
>> "@context": ... 
>> "@graph": [ 
>> { ... }, 
>> { ... } 
>> ] 
>> } 
>> 
>>> This way your client could look at the retrieved document for link
>> descriptions  
>>> before trying to dereference them or the ApiDocumentation (as I described in 
>>> me earlier mail). 
>> 
>> Right. The only "problem" is that you "leak" the information that
>> "schema.org/offer" is a hydra:Link to the public and don't restrict it to
>> the scope of your API (an ApiDocumentation limits the scope to the API itself).
> 
> Leak sounds very bad ;) Exactly how does ApiDocumentation restrict my
> statement "schema:offers is a hydra:Link" to my api?
>

See my comments above.

> 
> General feeling: this stuff is much more complicated than it seemed when I
> read the json-ld spec.
>

This is probably true. Genreally speaking, if implementing Hypermedia APIs were easy everyone would be doing perfect REST clients and servers. Unfortunately the problem is not easy and so the solution is inherently quite complex to if you want relative flexibility. There are other options like HAL or SIREN, each with their own limitations. An they are not much less complex either anyway IMO.

> 
> Best regards,
> 
> Dietrich Schulten 
> 
> -- 
> Escalon System-Entwicklung 
> Inh. Dietrich Schulten 
> Bubenhalde 10 
> 74199 Donnbronn

[1] http://www.w3.org/TR/json-ld/#flattened-document-form

Received on Saturday, 11 October 2014 08:51:18 UTC