TS-29: JSON Schema
This technical standard sets out some guidelines for JSON schema. The emphasis on this technical standard is on designing JSON schema, though there is also some information on using published JSON schemas such as JSON-LD.
JSON Schema provides a vocabulary for describing the structure of JSON data. Documentation, code, and other artifacts can be generated from JSON Schema definitions, but the primary use case if to validate JSON documents.
JSON schema is commonly used to define the structure of data transferred between systems via network APIs. It may also be used for input validation, to define interfaces for data structures constructed at runtime, and to define data persistence schema (eg. document stores).
Content type
The official content type for JSON Schema is application/schema+json. It is
RECOMMENDED to use this content type when serving JSON Schema via HTTP.
Versions
JSON Schema was originally defined as an IETF standard, but is now maintained as a community project. Versions 00 through 04 were published as IETF drafts, while draft-05 moved to the community project.
The current version of JSON Schema is Draft 2020-12. It is RECOMMENDED to use
this version for new projects. The metaschema for this version is
https://json-schema.org/draft/2020-12/schema.
Cross-references
JSON Schema defines a $ref
keyword to link schema from other schema.
It is RECOMMENDED to use $ref to share common structures, keeping schemas
modular and reusable. Prefer schema composition over inheritance. Designing your
schema for modularity is how, like code, you can best manage growing complexity
at scale.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Locale",
"description": "Locale, composed from a BCP-47 language tag, ISO-3166 alpha-2 country code, and Olsen IANA timezone ID.",
"type": "object",
"required": [
"country_code",
"language"
],
"properties": {
"country_code": {
"$ref": "country-code.schema.json"
},
"language": {
"$ref": "language-code.schema.json"
},
"timezone": {
"$ref": "timezone.schema.json"
}
}
}However, as per the JSON Schema documentation, it is RECOMMENDED to not require
client applications to automatically resolve schema that are referenced from
other schema via the $ref attribute. Instead, it is RECOMMENDED that JSON
Schema publishers automatically swap $ref properties for inline schema, using
a build step.
A command-line tool is available to do this.
JSON Hyper-Schema
JSON Hyper-Schema is an extension to JSON Schema that adds properties to allow the embedding of hypermedia links in JSON documents. It builds on URI Templates (RFC 6570) and other standards.
The main use case for JSON Hyper-Schema is to embed hypermedia controls in JSON documents that enable APIs to be navigated, and explored in a dynamic way (ie. without clients necessarily having initial knowledge of all available resources and endpoints).
The following example, taken from the specification, adds a single link:
{
"type": "object",
"properties": {
"id": {
"type": "number",
"readOnly": true
}
},
"links": [
{
"rel": "self",
"href": "thing/{id}"
}
]
}JSON Hyper-Schema adds the links property, which must be an array of "link
description objects" (LDO).
Any IANA-registered link relation type can be used to define the link relation
type (rel). This defines the semantics of the link in terms of its
relationship to the resource. The table below describes some of the most
commonly used link relation types.
Type | Description |
|---|---|
| Identifies the resource itself. |
| Indicates the next or previous resource in a sequence, eg. in a paginated list. |
| Refers to the first or last resource in a sequence. |
| Refers to a parent resource in a hierarchy of resources. |
It is RECOMMENDED to use a small subset of link relation types, and to use them consistently across all endpoints in a hypermedia API. You SHOULD NOT define custom relations, unless absolutely necessary when no standard ones fit the use case.
The following best practices also apply for JSON Hyper-Schema:
- Each response should contain minimal links, just enough for clients to navigate deeper.
- Do not expose an entire API graph in any single response, except for simple APIs composed of just a few endpoints.
- It is RECOMMENDED to always include "self" links to the current resource, wherever relevant.
- Use simple, minimalist URI templates, with only necessary path parameters (variables).
- Provide all required template variables in the response object.
- Use
templatePointersto clearly map data to template variables. - Use
targetSchemato describe expected response formats. - Use
targetHintsfor media types and methods. - Add
titleproperties for human-readable link descriptions.
OpenAPI
OpenAPI is another dialect of JSON Schema, used to describe HTTP "RESTful" APIs. It is a superset of JSON Schema, adding additional properties to describe HTTP-specific concepts.
for all JSON Schema, but there are a few OpenAPI-specific things to keep in mind.
JSON-LD (JSON for Linked Data)
JSON-LD is a schema used to imbue JSON documents with semantic meaning and to embed linked data.
JSON-LD bridges the gap between concepts from the semantic web and modern web service APIs. The idea is that machines can understand and explore data in JSON documents, similarly to how semantic web technologies like RDF and OWL work.
JSON-LD defines two main properties:
@contextreferences a vocabulary that describes the concepts in the document.@typeindicates the type of the entity represented by an object.
Schema.org is perhaps the most popular vocabulary for JSON-LD. Its vocabulary can also be embedded in HTML documents using microdata or RDFa.
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Jane Doe",
"jobTitle": "Professor",
"telephone": "(425) 123-4567",
"url": "http://www.janedoe.com"
}It is RECOMMENDED to reuse existing vocabularies, such as Schema.org, wherever there is a good fit for an application’s schema. Even if a vocabulary does not cover all the concepts required by the application, it is still better to try to reuse existing vocabularies, even if only partially. This saves time and effort designing new schemas, and it also helps to keep data as interoperable as possible with other systems. Even if interoperability is not a requirement now, it may be in the future.
For example, Schema.org’s Person type, which defines
properties such as givenName, familyName, jobTitle, and telephone, is a
good basis from which to design a schema for users, customers, or other such
entities.
For further guidance on using JSON-LD, the W3C maintains a JSON-LD Best Practices document.
JSON Pointer
IETF RFC 6901 defines a syntax
for identifying a specific value in a JSON document. A JSON Pointer is a string
beginning with a forward slash /, with each subsequent slash separating path
segments that identify nested objects and arrays:
/path/to/property
Elements of arrays can be referenced using zero-indexed numeric indices:
/users/0/name
An empty string "" refers to an entire document.
There are a couple of special characters. The / character in a property name
is escaped as ~1. The ~ character is escaped as ~0. It is RECOMMENDED to
not include these, or any other special characters, in property names, to make
traversal of JSON data structures as easy as possible for all clients.
JSON Pointer is used for data extraction, validation, and transformation. It is also used for partial updates via JSON Patch operations. Relevant to this technical standard, JSON Pointer syntax is RECOMMENDED for creating cross-references within JSON documents. Example:
{
"categories": [
{
"id": "electronics",
"name": "Electronics"
},
{
"id": "computers",
"name": "Computers",
"parentCategory": "/categories/0"
},
{
"id": "laptops",
"name": "Laptops",
"parentCategory": "/categories/1"
}
],
"products": [
{
"id": "laptop1",
"name": "UltraBook Pro",
"price": 1299.99,
"categoryRef": "/categories/2",
"relatedProducts": ["/products/1"]
},
{
"id": "laptop2",
"name": "DevBook Max",
"price": 1499.99,
"categoryRef": "/categories/2",
"relatedProducts": ["/products/0"]
}
]
}JSON Type Definition (JTD)
JSON Type Definition (JTD) is an alternative schema language for JSON documents. It was created in response to JSON Schema and is designed to be simpler, focusing on structural and type validation, with a lighter weight vocabulary and fewer constraints.
{
"properties": {
"name": { "type": "string" },
"age": { "type": "uint8" },
"email": { "type": "string" },
"isSubscribed": { "type": "boolean" },
"registrationDate": { "type": "timestamp" }
},
"optionalProperties": {
"phoneNumber": { "type": "string" },
"address": {
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"country": { "type": "string" }
},
"optionalProperties": {
"postalCode": { "type": "string" }
}
},
"tags": {
"elements": {
"type": "string"
}
}
}
}JSON Schema is the de facto standard for JSON schema, and it is RECOMMENDED for its expressive power and readily-available libraries and tooling. However, JTD is a good alternative for simple use cases, especially where type safety is the primary concern (rather than full schema validation),and it is mentioned here for completeness.
Useful links
- Hyperjump — Free-to-use online JSON Schema validation tool.
- JSON Schema Store — A repository of JSON Schema for commonly-used JSON configuration files such as package.json.