- From: Dietrich Schulten <ds@escalon.de>
- Date: Sat, 25 Mar 2017 12:18:27 +0100
- To: public-hydra@w3.org
- Message-ID: <d24ed772-6e5d-a5df-d044-aa93cd68bb46@escalon.de>
Hi Alexander, Am 13.02.2017 um 21:33 schrieb Alexander Surinov: > > But Image I have the following plain JSON array as top level JSON object. > > [ > > { > > "id": 638865, > > "first_name": "Emma", > > "last_name": "Stone" > > }, > > { > > "id": 1053682, > > "first_name": "Emma", > > "last_name": "Watson" > > } > > ] > > So, my question is: How can I convert JSON message to JSON-LD format > when source JSON message represented as JSON array? > > As described in JSON-LD specs we can add @context as HTTP Link Header > using the http://www.w3.org/ns/json-ld#context link relation. Ok, but > where I should define @type and @id for JSON object? > > I take it by JSON object you mean the JSON array your response consists of. Unfortunately, what you want to do is impossible. First of all, in JSON an array cannot have an attribute, it can only contain comma-separated items. In Javascript, an array can have an attribute which is not part of the array items: $ node > var array = [ "foo", "bar" ]; > array [ 'foo', 'bar' ] > array["@id"] = "http://array.example.com"; > array [ 'foo', 'bar', '@id': 'http://array.example.com' ] > array[0] 'foo' > array[1] 'bar' > array[2] undefined <-- @id is not an array item > array["@id"] 'http://array.example.com' Not so in JSON. Therefore JSON does not allow to attach an @id to a list, technically. That is a limitation of JSON, not of JSON-LD. But it goes deeper than that. Consider the JSON-LD array below at the "url" attribute. { "@context": "http://schema.org/", "@type": "Person", "@id": "http://janedoe.com", "name": "Jane Doe", "url": ["http://www.janedoe.com", "http://www.janedoe.de"] } One might think that the attribute "url" has an array value. However, that is not the case in the underlying datamodel of JSON-LD (RDF), as you see in the normalized representation (JSON-LD playground http://tinyurl.com/lc4pnxq): <http://janedoe.com> <http://schema.org/name> "Jane Doe" . <http://janedoe.com> <http://schema.org/url> <http://www.janedoe.com> . <http://janedoe.com> <http://schema.org/url> <http://www.janedoe.de> . <http://janedoe.com> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Person> . The underlying data model represents the array items in such a way that the subject http://janedoe.com has the predicate http://schema.org/url twice. There is no array in the underlying data model. You also have to be aware that this makes it impossible to make a JSON-LD array a "remote" resource. Consider the local JSON-LD array which is the value of the "address" attribute below: { "@context": "http://schema.org/", "@type": "Person", "@id": "http://janedoe.com", "name": "Jane Doe", "address": [ { "@type": "PostalAddress", "streetAddress": "Bubenhalde 10", "addressLocality": "Untergruppenbach" }, { "@type": "PostalAddress", "streetAddress": "Wieblinger Weg 35", "addressLocality": "Heidelberg" } ] } You might think that you could easily factor out the local list of addresses as a remote related resource of the Person like that: { "@context": "http://schema.org/", "@type": "Person", "@id": "http://janedoe.com", "name": "Jane Doe", "address": {"@id": "http://janedoe.com/addresses" } } Because dereferencing the URL "http://janedoe.com/addresses" could give you the following representation: [ { "@type": "PostalAddress", "streetAddress": "Bubenhalde 10", "addressLocality": "Untergruppenbach" }, { "@type": "PostalAddress", "streetAddress": "Wieblinger Weg 35", "addressLocality": "Heidelberg" } ] However, in JSON-LD the two representations do not mean the same. In RDF the *local* array resolves to two statements, i.e. Jane Doe really has two addresses (JSON-LD Playground http://tinyurl.com/lfk2e8v): <http://janedoe.com> <http://schema.org/address> _:b0 . <http://janedoe.com> <http://schema.org/address> _:b1 . whereas the *remote* array resolves to one statement (http://tinyurl.com/mk9gjwp) <http://janedoe.com> <http://schema.org/address> <http://janedoe.com/addresses> . By making the addresses remote, you no longer state that Jane Doe has two addressses, not even after dereferencing the URL. You state that she has one address. The fact that dereferencing the list gives you two addresses does not make a difference here. It is not possible to have a remote array in pure JSON-LD which correctly resolves to the equivalent of a local JSON-LD array. You have to introduce an intermediary object in a vocab like hydra:Collection and provide a definition how the collection items can be attached back to the parent. That is what the Hydra collection construct accomplishes (https://www.w3.org/community/hydra/wiki/Collection_Design). Basically, rather than having an address attribute on the person, you say that the person has a related hydra:collection: { "@context": { "@vocab": "http://schema.org/", "hydra": "http://www.w3.org/ns/hydra/core#", "hydra:property": {"@type": "@vocab"} }, "@type": "Person", "@id": "http://janedoe.com", "name": "Jane Doe", "hydra:collection": { "@id": "http://janedoe.com/addresses", "@type": "hydra:Collection", "hydra:manages": { "hydra:property": "address", "hydra:subject": "http://janedoe.com" } } } Obviously that breaks your plain JSON client. What you could do is to return the old structure for clients which do not Accept: application/ld+json, and the new structure only for clients that do. I find that quite cumbersome and unnatural from the perspective of a JSON api author, but it would have to be solved in JSON-LD by introducing the concept of a remote JSON-LD array. Last time I tried that I was told there is no chance for something like that, so I stopped pushing in that direction ;-) I still think the lack of a concept for remote collections is a major shortcoming of JSON-LD. Your problem illustrates that quite nicely. @Markus, Gregg: I guess your position remains unchanged here. Or would it make sense to open an issue for JSON-LD to support remote arrays - basically making the hydra:Collection a first-class citizen in JSON-LD, so to speak? If you are interested, I can explain what I mean by that. Best, Dietrich
Received on Saturday, 25 March 2017 11:19:02 UTC