JSON-AD: The Atomic Data serialization format
Although you can use various serialization formats for Atomic Data, JSON-AD
is the default and only required serialization format.
It is what the current Rust and Typescript / React implementations use to communicate.
It is designed to feel familiar to developers and to be easy and performant to parse and serialize.
It is inspired by JSON-LD.
It uses JSON, but has some additional constraints:
- Every single Object is a
Resource
. - Every Key is a
Property
URL. Other keys are invalid. Each Property URL must resolve to an online Atomic Data Property. - The
@id
field is special: it defines theSubject
of theResource
. If you send an HTTP GET request there with ancontent-type: application/ad+json
header, you should get the full JSON-AD resource. - JSON arrays are mapped to Resource Arrays
- Numbers can be Integers, Timestamps or Floats.
- JSON booleans map to Booleans.
- JSON strings can be many datatypes, including String, Markdown, Date or other.
- Nested JSON Objects are Nested Resources. A Nested Resource can either be Anonymous (without an
@id
subject) or a Named Nested Resource (with an@id
subject). Everywhere a Subject URL can be used as a value (i.e. all properties with the datatype atomicURL), a Nested Resource can be used instead. This also means that an item in anResourceArray
can be a Nested Resource. - The root data structure must either be a Named Resource (with an
@id
), or an Array containing Named Resources. When you want to describe multiple Resources in one JSON-AD document, use an array as the root item.
Let's look at an example JSON-AD Resource:
{
"@id": "https://atomicdata.dev/properties/description",
"https://atomicdata.dev/properties/datatype": "https://atomicdata.dev/datatypes/markdown",
"https://atomicdata.dev/properties/description": "A textual description of something. When making a description, make sure that the first few words tell the most important part. Give examples. Since the text supports markdown, you're free to use links and more.",
"https://atomicdata.dev/properties/isA": [
"https://atomicdata.dev/classes/Property"
],
"https://atomicdata.dev/properties/shortname": "description"
}
The mime type (for HTTP content negotiation) is application/ad+json
(registration ongoing).
Nested, Anonymous and Named resources
In JSON-AD, a Resource can be respresented in multiple ways:
- Subject: A URL string, such as
https://atomicdata.dev/classes/Class
. - Named Resource: A JSON Object with an
@id
field containing the Subject. - Anonymous Nested Resource A JSON Object without an
@id
field. This is only possible if it is a Nested Resource, which means that it has a parent Resource.
Note that this is also valid for ResourceArrays
, which usually only contain Subjects, but are allowed to contain Nested Resources.
In the following JSON-AD example, the address
is a nested resource:
{
"@id": "https://example.com/arnold",
"https://example.com/properties/address": {
"https://example.com/properties/firstLine": "Longstreet 22",
"https://example.com/properties/city": "Watertown",
"https://example.com/properties/country": "the Netherlands",
}
}
Nested Resources can be named or anonymous. An Anonymous Nested Resource does not have it's own @id
field.
It does have its own unique path, which can be used as its identifier.
The path
of the anonymous resource in the example above is https://example.com/arnold https://example.com/properties/address
.
JSON-AD Parsers, serializers and other libraries
- Typescript / Javacript: @tomic/lib JSON-AD parser + in-memory store. Works with @tomic/react for rendering Atomic Data in React.
- Rust: atomic_lib has a JSON-AD parser / serializer (and does a lot more).
Canonicalized JSON-AD
When you need deterministic serialization of Atomic Data (e.g. when calculating a cryptographic hash or signature, used in Atomic Commits), you can use the following procedure:
- Serialize your Resource to JSON-AD
- Do not include empty objects, empty arrays or null values.
- All keys are sorted alphabetically (lexicographically) - both in the root object, as in any nested objects.
- The JSON-AD is minified: no newlines, no spaces.
The last two steps of this process is more formally defined by the JSON Canonicalization Scheme (JCS, rfc8785).