This document is licensed under a Creative Commons Attribution 3.0 License.
JSON-LD Framing allows developers to query by example and force a specific tree layout to a JSON-LD document.
This document is merely a public working draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organisation.
This document is an experimental work in progress.
A JSON-LD document is a representation of a directed graph. A single directed graph can have many different serializations, each expressing exactly the same information. Developers typically work with trees, represented as JSON objects. While mapping a graph to a tree can be done, the layout of the end result must be specified in advance. A Frame can be used by a developer on a JSON-LD document to specify a deterministic layout for a graph.
This document is a detailed specification for a serialization of Linked Data in JSON. The document is primarily intended for the following audiences:
To understand the basics in this specification you must first be familiar with JSON, which is detailed in [RFC4627]. You must also understand the JSON-LD Syntax [JSON-LD], which is the base syntax used by all of the algorithms in this document, and the JSON-LD API [JSON-LD-API]. To understand the API and how it is intended to operate in a programming environment, it is useful to have working knowledge of the JavaScript programming language [ECMA-262] and WebIDL [WEBIDL]. To understand how JSON-LD maps to RDF, it is helpful to be familiar with the basic RDF concepts [RDF-CONCEPTS].
The intent of the Working Group and the Editors of this specification is to eventually align terminology used in this document with the terminology used in the RDF Concepts document to the extent to which it makes sense to do so. In general, if there is an analogue to terminology used in this document in the RDF Concepts document, the preference is to use the terminology in the RDF Concepts document.
The following is an explanation of the general terminology used in this document:
@value
,
@list
or @set
and it has one or more keys
other than @id
.@id
key._:
.There are a number of ways that one may participate in the development of this specification:
This API provides a clean mechanism that enables developers to convert JSON-LD data into a a variety of output formats that are easier to work with in various programming languages. If a JSON-LD API is provided in a programming environment, the entirety of the following API must be implemented.
The JSON-LD processor interface is the high-level programming structure that developers use to access the JSON-LD transformation methods. The definition below is an experimental extension of the interface defined in the [JSON-LD-API].
The JSON-LD API signatures are the same across all programming languages. Due
to the fact that asynchronous programming is uncommon in certain languages, developers may
implement processor with a synchronous interface instead. In that case, the callback
parameter must not be included and the result must be returned as return value instead.
[NoInterfaceObject]
interface JsonLdProcessor {
void frame (object or object[] or IRI input, object or IRI frame, object or IRI? context, JsonLdCallback callback, optional JsonLdOptions? options);
};
frame
input
using the
frame
according to the steps in the
Framing Algorithm. The input
is used to build the framed output and is returned if there are no errors.
If there are no matches for the frame, null must be
returned. Exceptions must be thrown if there are errors.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
input | object or object[] or IRI | ✘ | ✘ | The JSON-LD object or array of JSON-LD objects to perform the framing upon or an IRI referencing the JSON-LD document to frame. |
frame | object or IRI | ✘ | ✘ | The frame to use when re-arranging the data of input ; either
in the form of an JSON object or as IRI. |
context | object or IRI | ✔ | ✘ | An optional external context to use additionally to the context embedded in
input when expanding the input . |
callback | JsonLdCallback | ✘ | ✘ | A callback that is called when processing is complete on
the given input . |
options | JsonLdOptions | ✔ | ✔ | A set of options that may affect the framing algorithm such as, e.g., the input document's base IRI. |
void
The JsonLdCallback is used to return a processed JSON-LD representation as the result of processing an API method.
See JsonLdCallback definition in [JSON-LD-API].
This section describes datatype definitions used within the JSON-LD API.
The JsonLdOptions type is used to convert a set of options to an interface method.
See JsonLdOptions definition in [JSON-LD-API].
All algorithms described in this section are intended to operate on language-native data structures. That is, the serialization to a text-based JSON document isn't required as input or output to any of these algorithms and language-native data structures must be used where applicable.
This specification adds a number of keywords to the ones defined in the [JSON-LD] specification:
@default
@explicit
@omitDefault
@embed
@null
All JSON-LD tokens and keywords are case-sensitive.
@context
keyword.
Framing is the process of taking a JSON-LD document, which expresses a graph of information, and applying a specific graph layout (called a Frame).
Framing makes use of the Node Map Generation algorithm to place each object defined in the JSON-LD document into a flat list of objects, allowing them to be operated upon by the framing algorithm.
@id
to a parent JSON object and property
or parent array.This algorithm is a work in progress. Presently, it only works for documents without named graphs.
Currently, framing allows just to select node definitions based
on @type
matching or duck typing for included properties. It allows value properties to
be explicitly matched based on defining the property and excluding things that are undefined, but it
does not allow to be more specific about the types of values selected. Allowing this is currently
being discussed.
The framing algorithm takes an JSON-LD input (expanded input) and an input frame (expanded frame) that have been expanded according to the Expansion Algorithm, and a number of options and produces JSON-LD output.
Create framing context using null for the map of embeds,
the object embed flag set to true, the
explicit inclusion flag set to false, and the
omit default flag set to false along with map of flattened subjects
set to the @merged
property of the result of performing the
Node Map Generation algorithm on
expanded input. Also create results as an empty array.
Invoke the recursive algorithm using framing context (state), the map of flattened subjects (subjects), expanded frame (frame), result as parent, and null as active property.
The following series of steps is the recursive portion of the framing algorithm:
@type
property containing
one or more IRIs match any node definition
with a @type
property including any of those IRIs.@type
property only
a empty JSON object, matches any node definition
with a @type
property, regardless of the actual values.@embed
and @explicit
using the current values
for object embed flag and explicit inclusion flag from state if not found.@id
and id.@id
equal to id, element has
already been embedded and can be overwritten, so set embedOn to true.@list
, then
create a JSON object named list with the key @list
and
the value of an empty array. Append list to property in
output. Process each listitem in the @list
array as follows:
@id
of listitem as the key
and the node definition from the original map of flattened subjects
as the value. Pass the first value from
frame for property as frame, list
as parent, and @list
as active property.@list
in list.@id
of item as the key and
the node definition from the original map of flattened subjects
as the value. Pass the first value from
frame for property as frame, output
as parent, and property as active property.
@omitDefault
which is true or if it does not contain
@omitDefault
but the value of omit default flag
true.@preserve
and a value that is a copy of the value
of @default
in frame if it exists, or the string
@null
otherwise.At the completion of the recursive algorithm, results will contain the top-level node definitions.
The final two steps of the framing algorithm require
results to be compacted according to the
Compaction Algorithm by using the
context provided in the input frame. If the frame has no context, compaction
is performed with an empty context (not a null context). The compaction result must use
the @graph
keyword at the top-level, even if the context is empty or if there
is only one element to put in the @graph
array. Subsequently, replace all key-value
pairs where the key is @preserve
with the value from the key-pair. If the value
from the key-pair is @null
, replace the value with null. If,
after replacement, an array contains only the value null remove the value, leaving
an empty array. The resulting value is the final JSON-LD output.
This algorithm replaces an already embedded node definition with a node reference. It then recursively removes any entries in the map of embeds that had the removed node definition in their parent chain.
About as clear as mud
The current behaviour avoids embedding the same data multiple times in the result makes it difficult to work with the output. A proposal to change this to "agressive re-embedding" is currently being discussed.
The algorithm is invoked with a framing context and subject id id.
@id
of id,
removing that definition from the map, and then removing the dependents for the parent id
recursively by repeating this step. This step will terminate when there are no more embed
entries containing the removed node definition's @id
in their
parent chain.This algorithm recursively embeds property values in node definition output, given a framing context, input node definition element, active property, and output.
@list
,
then create a new JSON object with a key @list
and
a value of an empty array and add it to output, appending if output
is an array, and appending to active property otherwise. Recursively call this
algorithm passing item as element, @list
as active property,
and the new array as output. Continue to the next item.@id
of item:
This section is non-normative.
This section is included merely for standards community review and will be submitted to the Internet Engineering Steering Group if this specification becomes a W3C Recommendation.
application/json
MIME media type.eval()
function. It is recommended that a conforming parser does not attempt to
directly evaluate the JSON-LD frame and instead purely parse the
input into a language-native data structure.Fragment identifiers have no meaning with application/frame-ld+json resources.
A large amount of thanks goes out to the JSON-LD Community Group participants who worked through many of the technical issues on the mailing list and the weekly telecons - of special mention are Niklas Lindström, François Daoust, and Zdenko 'Denny' Vrandečić. The editors would like to thank Mark Birbeck, who provided a great deal of the initial push behind the JSON-LD work via his work on RDFj. The work of Dave Lehn and Mike Johnson are appreciated for reviewing, and performing several implementations of the specification. Ian Davis is thanked for this work on RDF/JSON. Thanks also to Nathan Rixham, Bradley P. Allen, Kingsley Idehen, Glenn McDonald, Alexandre Passant, Danny Ayers, Ted Thibodeau Jr., Olivier Grisel, Josh Mandel, Eric Prud'hommeaux, David Wood, Guus Schreiber, Pat Hayes, Sandro Hawke, and Richard Cyganiak for their input on the specification.