RE: In-place hydra:Link

On 7 Okt 2014 at 18:46, Dietrich Schulten wrote:
>> 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:
>> 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?

Yes


> What makes a jsonld object a vocab? Do we have documentation
> somewhere which describes how to write a vocab with json-ld?

It makes it a vocabulary if it defines a vocabulary. Vocabularies are
defined by using other vocabularies like, e.g., RDFS [1], Hydra or also OWL.
So whenever you define properties or classes, you are effectively defining a
vocabulary. 


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

Yes, it was just a very simple example. Have a look at the definition of
Hydra (it's also included at the end of the spec).


> Is it mandatory to write my own vocabulary in order to specify that an
> attribute in my responses is meant to be dereferenced?

No, you could also simply state that the value is of type hydra:Resource,
i.e., it is a dereferenceable resource.


> My vocabulary should then be of @type ApiDocumentation, I guess.

An ApiDocumentation defines how elements (properties, classes, ...) are to
be interpreted in the context of a specific Web API. Vocabulary definitions
on the other hand apply globally for everyone.


> That would mean that the documentation for an api cannot be inlined, it
> must be downloaded (and generated) separately from the responses. Hm.

Yes, but you can use other methods to avoid the need for an ApiDocumentation
(hydra:Resource, inline operations, etc.).


>> 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 ;)

Yes


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

Just define the value of that property (you call it attribute) to be of type
hydra:Resource.

   "comments": {
      "@id": "http://api.example.com/vocab#comment",
      "@type": "hydra:Resource"
   }

(of course you can also add other types, just make it an array)


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

You can certainly do that as well. The discussion we are having here is
really about theoretical purity. In RDF, IRIs are just identifiers, not
hyperlinks. Hydra allows you to make it explicit which of those IRIs can be
expected to be dereferenceable. That's all. Nothing prevents you to simply
"follow your nose" and be prepared to run against a wall in some cases :-)


> "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?

It is possible with both JSON-LD and Hydra as I outlined above.


>>>> {
>>>> "@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?

See above. Let me know if that explanation didn't clarify it.

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

Quite simple: by definition. Clients need to keep those statements separated
from other statements.


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

We are really discussing corner cases and theoretical pureness here. If you
look at the HydraConsole for example, it will render all @ids as clickable
hyperlinks, regardless of whether it is defined to be of type hydra:Resource
or whether the property is of type hydra:Link.


Cheers,
Markus


[1] http://www.w3.org/TR/rdf-schema/


--
Markus Lanthaler
@markuslanthaler

Received on Monday, 13 October 2014 16:07:35 UTC