Re: What is the JSON-LD API?

On 08/31/2011 01:35 PM, Danny Ayers wrote:
> I'm sure this has been discussed before, but it only just clicked for
> me (dogwalks are good!).
>
> JSON stands for Javascript Object Notation, right?
>
> so if we say
>
>     var object = parse( // bunch of JSON-LD // )
>
> what methods does object support?
>
> Say we've got the description of a book, what about:
>
>     var object = parse( // bunch of JSON-LD // )
>     var book = object.book
>     var title = book.title
>
> But straight from RDF we're looking at something more like:
>
>     var graph = parse( // bunch of JSON-LD // )
>
>     var rdf_ns = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>     var dc_ns = "http://purl.org/dc/elements/1.1/"
>     var books_ns = "http://example.org/books#"
>
>     var books = graph.getSubjects(rdf_ns+"type", books_ns+"Book")
>
>     var titles = graphs.getObjects(books[0], rdf_ns+"type")
>
>     var title = titles[0]
>
> I'd say the challenge is to support accessor methods that look more
> like the first version above, and less like the second.
>
> But here the thing - ideally want this to work *without* needing a
> custom parser.
>
> Looking at it from this point of view, CURIES needn't be a
> complication, if we could do things like:
>
> Regular JSON developer version:
>     var object = parse( // bunch of JSON-LD // )
>     var title = object.book["title"]
>
> RDF person's version:
>     var object = parse( // bunch of JSON-LD // )
>     var p_title = { "dc", "http://purl.org/dc/elements/1.1/"  }
>     var title = object.book[p_title]

This is the point of JSON-LD framing:

Regular JSON developer version:

    var object = JSON.parse( /* JSON */ );
    var title = object.book.title;

JSON-LD developer version:

    var frame = {/* custom frame for an object containing a book */ };
    var object = jsonld.frame(JSON.parse( /* JSON-LD */ ), frame);
    var title = object.book.title;

A JSON-LD frame allows a developer to provide the specific structure 
they would like the incoming object to take on. The frame API then 
essentially "fills out" the frame using the incoming JSON-LD data.

Below is an example of framing adapted from the one on the json-ld.org 
playground [2]. It is very similar to the book example you were using above:

Suppose your application is expecting to receive a JSON-LD graph that 
contains a library and a book. The incoming JSON might take on many 
different structures -- for instance, it might be a flat structure:

var input = {
    "@context": {
       "@coerce": {
          "@iri": ["book", "chapter"]
       },
       "author": "http://purl.org/dc/elements/1.1/author",
       "title": "http://purl.org/dc/elements/1.1/title",
       "description": "http://purl.org/dc/elements/1.1/description",
       "Library": "http://example.org/vocab#Library",
       "library": "http://example.org/vocab#library",
       "Book": "http://example.org/vocab#Book",
       "book": "http://example.org/vocab#book",
       "Chapter": "http://example.org/vocab#Chapter",
       "chapter": "http://example.org/vocab#chapter"
    },
    "@subject": [
    {
       "@subject": "http://example.org/library",
       "@type": "Library",
       "book": "http://example.org/library/the-republic"
    }, {
       "@subject": "http://example.org/library/the-republic",
       "@type": "Book",
       "author": "Plato",
       "title": "The Republic",
       "chapter": "http://example.org/library/the-republic#introduction"
    }, {
       "@subject": "http://example.org/library/the-republic#introduction",
       "@type": "Chapter",
       "description": "An introductory chapter on The Republic.",
       "title": "The Introduction"
    }]
};

Here you can see that none of the subjects are embedded in a way that 
might feel more natural to a JSON developer. If a JSON developer would 
instead like to work with a library that has a book with a chapter in 
it, he can use the framing API with this frame:

var frame = {
    "@context": {
       "@coerce": {
          "@iri": ["book", "chapter"]
       },
       "author": "http://purl.org/dc/elements/1.1/author",
       "title": "http://purl.org/dc/elements/1.1/title",
       "description": "http://purl.org/dc/elements/1.1/description",
       "Library": "http://example.org/vocab#Library",
       "library": "http://example.org/vocab#library",
       "Book": "http://example.org/vocab#Book",
       "book": "http://example.org/vocab#book",
       "Chapter": "http://example.org/vocab#Chapter",
       "chapter": "http://example.org/vocab#chapter"
    },
    "@type": "Library",
    "book": {
       "@type": "Book",
       "chapter": {
          "@type": "Chapter"
       }
    }
};

The call:

var output = jsonld.frame(input, frame);

Will yield this output (when serialized to JSON):

{
     "@subject": "http://example.org/library",
     "book": {
         "@subject": "http://example.org/library/the-republic",
         "chapter": {
             "@subject": 
"http://example.org/library/the-republic#introduction",
             "description": "An introductory chapter on The Republic.",
             "title": "The Introduction",
             "@type": "Chapter"
         },
         "author": "Plato",
         "title": "The Republic",
         "@type": "Book"
     },
     "@type": "Library",
     "@context": {
         "book": "http://example.org/vocab#book",
         "chapter": "http://example.org/vocab#chapter",
         "description": "http://purl.org/dc/elements/1.1/description",
         "title": "http://purl.org/dc/elements/1.1/title",
         "Chapter": "http://example.org/vocab#Chapter",
         "author": "http://purl.org/dc/elements/1.1/author",
         "Book": "http://example.org/vocab#Book",
         "Library": "http://example.org/vocab#Library"
     }
}

Which means that the developer can access the title of the book like so:

output.book.title;

The developer can access the title of the chapter like so:

output.book.chapter.title;

Different JSON developers might want different structures for the same 
data. I expect a typical practice would be to define the frames for the 
objects in your application once, in some globally accessible 
variable/API, and then use the appropriate frame whenever input is 
received by your application. From there on out, your code acts just 
like it would normally.

This above example can be seen on the json-ld.org playground [3]. Click 
on the "Framed" tab. For a further explanation on how framing works, 
please see my earlier email to the list [1].

I definitely agree that the text explaining framing and its uses are 
lacking in the spec. We've been discussing that a bit on some other 
threads and I'm sure we'll be updating the spec language.

[1] http://lists.w3.org/Archives/Public/public-linked-json/2011Aug/0078.html
[2] http://json-ld.org/playground/
[3] http://tinyurl.com/jsonld-book-frame

-- 
Dave Longley
CTO
Digital Bazaar, Inc.

Received on Wednesday, 31 August 2011 20:37:45 UTC