Introduction
JSON-LD is a Linked Open Data serialization using the popular JSON (Javascript Object Notation) format that is convenient for both backend and browser based development. It is specified by the W3C as an official serialization. Continued development work happens in the JSON for Linking Data W3C Community Group.
The serialization for JSON-LD is friendly to developers through the use of context documents that specify the mapping between the key used in the json object and the RDF predicate used in the model. This abstraction allows the developer to work with existing patterns and frameworks, while the data is still managed as a graph underneath. This document describes the context used for CIDOC-CRM and other ontologies.
The context that provides the mapping of the terms used in the model is published as:
https://linked.art/ns/v1/linked-art.json
Media Type
The media type to use for representations in JSON-LD using the context is:
application/ld+json;profile="https://linked.art/ns/v1/linked-art.json"
This would be the value of the Content-Type
HTTP header on responses, and if there are other representations available via content negotiation, then it can be sent in requests in the Accept
header.
Core Requirements
There are several core requirements to keep in mind for JSON and JSON-LD representations:
- Terms are case sensitive.
Type
(the classcrm:E55_Type
), andtype
(the propertyrdf:type
) are different terms, separated only by the upper case of the initial letter. As described below, the JSON representation of the names of classes and properties is as consistent as possible. - Properties cannot be repeated on a single object. Instead, if there are multiple values for a property or multiple instances of a relationship, then the JSON will have an array as the value where each entry is considered to have that property. Linked Art does not use ordered lists (such as
rdf:List
).
Other Serialization Formats
Other serialization formats of the underlying graph may also be available, such as RDF/XML, Turtle, other standardized formats, or even non-standardized representations. These are not required in order to fully conform with the Linked Art API, and should not be assumed to exist. How to request these alternative serializations is documented in the protocol section.
Examples
The examples throughout the documentation use the JSON-LD serialization. Each has a link to the raw JSON-LD, and to load it into the invaluable JSON-LD playground where you can explore the details. Instead of trying to describe all of the predicates and classes (for that just read the CIDOC-CRM specification), we present the models for the known use cases in an attempt to be more practical and results oriented. We strive for usability and familiarity for developers, and the examples aim to present best practices at the same time as being easy to follow.
An example of the JSON-LD serialization for a painting, that is made of watercolor on a canvas support:
{
"@context": "https://linked.art/ns/v1/linked-art.json",
"id": "https://linked.art/example/object/2",
"type": "HumanMadeObject",
"_label": "Example Painting",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300033618",
"type": "Type",
"_label": "Painting",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300435443",
"type": "Type",
"_label": "Type of Work"
}
]
},
{
"id": "http://vocab.getty.edu/aat/300133025",
"type": "Type",
"_label": "Artwork"
}
],
"made_of": [
{
"id": "http://vocab.getty.edu/aat/300015045",
"type": "Material",
"_label": "watercolors"
}
],
"part": [
{
"type": "HumanMadeObject",
"_label": "Canvas Support",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300014844",
"type": "Type",
"_label": "Support",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300241583",
"type": "Type",
"_label": "Part Type"
}
]
}
],
"made_of": [
{
"id": "http://vocab.getty.edu/aat/300014078",
"type": "Material",
"_label": "canvas"
}
]
}
]
}
Context Design
The important part of the JSON-LD serialization is the shared context document. This context has some design constraints that it is useful to understand before looking at the data model and mapping from the ontology. In particular:
- The resulting JSON must be valid Linked Open Data and valid JSON-LD. The nested object structure in the JSON is a result of the graph of resources.
- The resulting JSON must be understandable by developers who are unfamiliar with both the model and RDF in general. If the target technical audience was developers who had the full suite of RDF tools at their disposal, then Turtle and SPARQL would likely be preferable. The serialization instead tries to make the content as accessible as the model will allow, to the broadest possible audience.
- The resulting JSON must be usable regardless of programming language or application environment to ensure the widest possible adoption and value. The context is designed to allow as many of conveniences as possible to be used, and to maximize the situations in which it can be used. Consistency is a core feature of usability, and as such the context tries to be as consistent as possible.
There are some challenges overlaid on these principles from the CIDOC-CRM ontology.
- The use of numbers in the class and properties runs counter to the understandable and usable principles.
- The use of - in the names of some classes and properties reduces usability, as it is not allowed as the name of a property in most programming languages.
- The use of the same name for a property, minus its number, is not possible in JSON-LD as the keys must map uniquely to a predicate.
- The use of underscores in class or property names is not common in Javascript or in RDF ontologies, which tend to prefer CamelCase.
- The same conceptual relationship between resources has different instantiations in the ontology, introducing unnecessary inconsistency. For example, the core partitioning relationships are class-specific rather than being a more obvious
part
relationship for everything.
The context tries to manage all of these issues in a practical and programmatically accesible way from the ontology definition.
Context
The following process is used to create the JSON-LD keys from the CIDOC-CRM ontology:
- Remove
@
symbols (id
not@id
) as a JSON-LD best practice - Remove namespaces from classes and properties (
E22_Man-Made_Object
notcrm:E22_Man-Made_Object
) as unnecessary with the context mapping - Remove the prefix numbers (
Human-Made_Object
notE22_Human-Made_Object
) as impossible to remember - Remove dashes (
HumanMade_Object
notHuman-Made_Object
) as invalid in class names - Use upper CamelCase for classes (
HumanMadeObject
notHumanMade_Object
) as common practice - Use lower snake_case for properties (
is_identified_by
) as generating camelCase is difficult automatically for such a broad set of terms - Remove
is_
,was_
,has_
andhad_
from the beginning of properties, as being inconsistently applied in the ontology and hard to remember (identified_by
notis_identified_by
; compare thecreated
anddestroyed
properties, which are not of the formwas_created
in the ontology) - Rename properties with collisions, from furthest down the hierarchy first, with a first effort of adding the range's class to the predicate name, but preferring a human understandable term
- Rename properties that are inconsistently named, when those properties are used
- Provide a single context with all of the terms, to facilitate ease of extensions using core terminology
- Include prefixes for commonly used ontologies (
skos
,schema
,rdf
) and vocabularies (aat
,tgn
,geonames
)
The context implements the notion that if a property can ever have multiple values, then it must always be an array. In JSON-LD this is done with @container: @set
on such properties, and you'll see many instances of this in the examples where a property has an array with a single object inside it.
The context is designed for JSON-LD 1.1, and uses the feature known as "scoped contexts": sub-contexts that are defined per class or per relationship that apply only within that term. This is used to map all of the the various partitioning relationships to part
and part_of
, regardless of the type of resource being partitioned. This feature makes the JSON much easier to read and write, without losing the semantic precision of the separate underlying terms.
Name collisions and naming inconsistencies in the ontology have been resolved as follows:
{% include "_include/prop_key_map.md" %}