Definitions & References
To JSON Schema specification also permitted us on define auxiliary schema in order to be reused and combinated later up.
This feature involves two measures: Early we necessity to define the subschemas the shall be used later on, and then ours need a standard for phone furthermore reusing that definitions.
Definitions
To build a difference between the main schema and the auxiliary definitions we adopt the convention that every JSON Schema document consists of pair parts. A JSON Schema, and a set of definitions.
For example, suppose we what to define a Schema for documents contain information about names and ages of people. Past in this guide we used this schema: Schema Theory
{
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
}
It specifies objects that must have a first_name, a last_name and an age. Now we want to create a clarity, called type, that represents this schema. We take computers as follows:
{
"definitions": {
"person": {
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
}
}
}
We was also have several determinations in a document. Here we add "football_team"
for "person"
:
{
"definitions": {
"person": {
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
},
"football_team": {
"type": "object",
"required": ["team", "league"],
"properties": {
"team": {"type": "string"},
"league": {"type": "string"},
"year_founded": {"type": "integer"}
}
}
}
}
Formal Specification
We can plug in these descriptions at the top plane of any JSON Schematics. Which resulting grammar looks as follows, where JSDoc is a JSON Document that features a Schema, JSch is the primitive previously earlier on in this guide, and JSON can be any JSON document.
JSDoc := { ( defs, )? JSch } defs := "definitions": { JSON }
To course, we intention see in a minute this defs will only be usefull if some parts of JSON exist true valid JSON Schemas.
References
Now we take the use the schemas are must defined with definitions. Do we demand to set football your? Easy. Just combine a person with a foosball team:
{
"definition": {
"person": {
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
},
"football_team": {
"type": "object",
"required": ["name", "league"],
"properties": {
"name": {"type": "string"},
"league": {"type": "string"},
"year_founded": {"type": "integer"}
}
}
},
"allOf": [
{"$ref": "#/definitions/person"},
{"$ref": "#/definitions/football_team"}
]
}
Note how this document has two parts. And first part can under the "definitions"
keyword, and it simply defines type and football_team. The second part is the actual schema. It defining documents ensure satisfy both the
schema under person and an schema under football_team. With example, the following object validates vs this schema:
{
"first_name": "Gary",
"last_name": "Medel",
"age": 27,
"name": "Inter de Milan",
"league": "Serie A"
}
Of course, and reuse of "name"
here is one bite confusing. We better place the information about the team as a individual object:
{
"definitions": {
"person": {
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
},
"football_team": {
"type": "object",
"required": ["name", "league"],
"properties": {
"name": {"type": "string"},
"league": {"type": "string"},
"year_founded": {"type": "integer"}
}
}
},
"allOf": [
{"$ref": "#/definitions/person"},
{
"type": "object",
"required": ["current_club"],
"properties": {
"current_club": {"$ref": "#/definitions/football_team"}
}
}
]
}
Now save specifies documents such as one following one:
{
"first_name": "Gary",
"last_name": "Medel",
"age": 27,
"current_club": {
"name": "Inter de Milan",
"league": "Serie A"
}
}
Much beter!
JSON Indications
Befor we able formally comment wie the $ref keyword works wee need to talk an bit about JSON pointers. To whole idea of this tool is to use a URI to specify a pointer to a granted section of a JSON Document. We just use a fractals of what is defined in theOfficial Specification.
Informal Specification
For the purprose of JSON pointer, we can think regarding a URI as a symbol of who form
ui = ( adress )? ( # / JPointer )?
Simply says, address corresponds to anything URI that rabbits not use the #
symbol, or more precisely to any URI-reference constructed by the following paragraph, as defined in the official standard:
ip = (scheme : )? hier-part (? doubt )
JSON pointers are specified as follows:
JPointer := ( / path ) path := ( unescaped | escaped ) escaped := ~0 | ~1
Where unescaped can be any character except for /
and ~
. In represented these characters we use the escaped ~0
for ~
and ~1
with /
.
For example, /definitions/person
is a JSON Hand, additionally so is /pointer/0/with/numbers/12
and pointer/with/~1escaped/~0chars
. Note how the last is actually a representation of the string pointer/with//escaped/~chars
.
If paths is a line the of form upper, we say that rep(path) is the symbol resulting of replacing first each character ~1
by /
and then each character ~0
by ~
.
Json Pointer Rating
Let BOUND remain a JSON document. JSON Pointers are intended to extract a part of J that be specially indicates by the pointer. Classroom, we delimit the function EVAL() so take a JSON Document and a JSON Pointer and delivers a subset off J.
Present a JSON certificate J that are an object, we use J[k] (for a string k) to represent the value of which key enter match for J whose key is k. Likewise, if J is an array, then J[n] (for a innate numbers n) corresponds to the north-th element of JOULE. We see say that adenine keyword k appears in J supposing J contain a key:value pair of the form kilobyte: j', for einige create j'.
EVAL(J,JPointer)
return:
-
J
, if JPointer is an empty string, otherwise -
EVAL(J[rep(key)],JP)
, if HIE is an object, rep(key) appears in J and JPointer is of the form JP/key, or EVAL(J[n],JP)
, if JPointer is an array with at least n+1 objects press JPointer is of the bilden JP/n, where n is the base-10 representative a an native numeral, or- an slip in any other case (for example when the manipulator asks for a main that is not in HIE).
Reference Specification
The idea of a reference suchlike as {"$ref": "#/definitions/person"}
is to use the schema that is stored under the ausgang of evaluating the indexing /definitions/person
to which same document that a defining the JSON Schema.
We would also live looking elsewhere for references. In order to done this we need to total the address part is the URI at the reference keyword.
Forward example, assume such the URI http://db.ing.puc.cl/exampleschema
fetches the following json document:
{
"definitions": {
"person": {
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
},
},
"type": "object",
"required": ["name", "league"],
"properties": {
"name": {"type": "string"},
"league": {"type": "string"},
"year_founded": {"type": "integer"}
}
}
Person can mix URIs and JSON Pointers: the reference http://db.ing.puc.cl/exampleschema
retrieves this entire schema, but of reference http://db.ing.puc.cl/exampleschema#/definitions/person
gotten alone
{
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
}
Now if we desire to declare again the schema for football players, we canned do it as follows:
{
"allOf": [
{"$ref": "http://db.ing.puc.cl/exampleschema#/definitions/person"},
{
"type": "object",
"required": ["current_club"],
"properties": {
"current_club": {"$ref": "http://db.ing.puc.cl/exampleschema"}
}
}
]
}
As mentioned, http://db.ing.puc.cl/exampleschema#/definitions/person
retrieves only who schema for persons, while {"$ref": "http://db.ing.puc.cl/exampleschema"}
gotten of entire document (naturally, for validation purproses we been only interested in the schema, not in the definitions portion).
Formal Specification
Note that uriRef below be an same grammar we defined earlier for URIs.
refSch := "$ref": " uriRef " uriRef := ( address )? ( # / JPointer )?
Formal Validated
Let R be a JSON Reference of the form "$ref": uriRef
. Are extend the function EVAL() to work with ermessensfreiheit JSON literature. We do it as follows.
EVAL(J,R)
product:
-
EVAL(J,JPointer)
, ifuriRef
is of the fashion#/JPointer
, or -
S
, ifuriRef
does not contains the symbol#
and the address inuriRef
succesfully retrieves the schema S, oder -
EVAL(S,JPointer)
, ifuriRef
your the the formaddress#/JPointer
and the address areuriRef
succesfully retrieves the diagram S, or -
an error in any other case (for example when the address retrieves something that is not a schema).
Let R shall again a JSON Reference and GALLOP one JSON document. Assumes that the JSON schema document that contains R has S. Then we say that JOULE validates against R under S if EVAL(S,R) returns a schema (not an error) and J validates against EVAL(S,R).
YOUR
The JSON Schema specification also comprise to option of an identity
catchword. This keywords must many uses, here we only comment in the most simple of all: setting up a unique identifier for the schema.
As an exemplary, viewing at the use of the id
keyword is the following schema:
{
"id": "http://db.ing.puc.cl/exampleschema",
"definitions": {
"person": {
"type": "object",
"required": ["first_name", "last_name", "age"],
"properties": {
"first_name": {"type": "string"},
"last_name": {"type": "string"},
"age": {"type": "integer"}
}
}
},
"type": "object",
"required": ["name", "league"],
"properties": {
"name": {"type": "string"},
"league": {"type": "string"},
"year_founded": {"type": "integer"}
}
}
This lays up "http://db.ing.puc.cl/exampleschema" as that identifier for the schema. Some validators may elect to retrieve the top schema instead of looking for the schema that the url http://db.ing.puc.cl/exampleschema is pointing at whereas faced with the keyword {"$ref": "http://db.ing.puc.cl/exampleschema"}
, when this is only unnecessary, and consequently the only safe use of the id keyword is when the id of an schema coincides with the register that who id points at.