Structuring a complex schema

When writing computer programs of even moderate complexity, it's commonly accepted that "structuring" the program into reusable functions is better than copying-and-pasting duplicate bits of code everywhere they are used. Likewise in JSON Schema, for anything but the most trivial schema, it's really useful to structure the schema into parts that can be reused in a number of places. This chapter will present the tools available for reusing and structuring schemas as well as some practical examples that use those tools.

Schema Identification

Like any other code, schemas are easier to maintain if they can be broken down into logical units that reference each other as necessary. In order to reference a schema, we need a way to identify a schema. Schema documents are identified by non-relative URIs.

Schema documents are not required to have an identifier, but you will need one if you want to reference one schema from another. In this documentation, we will refer to schemas with no identifier as "anonymous schemas".

In the following sections we will see how the "identifier" for a schema is determined.

URI terminology can sometimes be unintuitive. In this document, the following definitions are used.

Even though schemas are identified by URIs, those identifiers are not necessarily network-addressable. They are just identifiers. Generally, implementations don't make HTTP requests ( https:// ) or read from the file system ( file:// ) to fetch schemas. Instead, they provide a way to load schemas into an internal schema database. When a schema is referenced by it's URI identifier, the schema is retrieved from the internal schema database.

Base URI

Using non-relative URIs can be cumbersome, so any URIs used in JSON Schema can be URI-references that resolve against the schema's base URI resulting in a non-relative URI. This section describes how a schema's base URI is determined.

Base URI determination and relative reference resolution is defined by RFC-3986. If you are familiar with how this works in HTML, this section should feel very familiar.

Retrieval URI

The URI used to fetch a schema is known as the "retrieval URI". It's often possible to pass an anonymous schema to an implementation in which case that schema would have no retrieval URI.

Let's assume a schema is referenced using the URI https://example.com/schemas/address and the following schema is retrieved.

< " type " : "object" , " properties " : < " street_address " : < " type " : "string" >, " city " : < " type " : "string" >, " state " : < " type " : "string" >> , " required " : [ "street_address" , "city" , "state" ] >

The base URI for this schema is the same as the retrieval URI, https://example.com/schemas/address .

$id

You can set the base URI by using the $id keyword at the root of the schema. The value of $id is a URI-reference without a fragment that resolves against the retrieval-uri. The resulting URI is the base URI for the schema.