Most of the questions that center around referencing data involve comparing the values of properties. This typically comes in a few flavors:
- How do I require that property
A
is less than propertyB
? - How do I require that property
A
is one of a list of things specified by propertyB
? - How do I require that…
Requiring that A < B
We want to specify a minimum for B
that is the value of A
. Unfortunately, JSON Schema doesn’t have a mechanism that allows this; it only has minimum
which must be a static (unchanging) value. Specifically, as enforced by the meta-schema, minimum
must be a number.
1
2
3
4
5
6
7
8
9
10
{
"type": "object",
"properties": {
"A": { "type": "number" },
"B": {
"type": "number",
"minimum": ???
}
}
}
We can’t put a number here because we want that value to depend on the value of A
.
To solve this, we remove the minimum
keyword and add the data
keyword. Inside data
, we specify minimum
with a plain JSON Pointer (not URI-encoded) that points to where in the instance we want to get the value; in this case, from the A
property.
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"$schema": "https://json-everything.net/meta/data-2022",
"type": "object",
"properties": {
"A": { "type": "number" },
"B": {
"type": "number",
"data": {
"minimum": "/A"
}
}
}
}
Passes | Fails |
---|---|
{ "A": 5, "B": 10 } | { "A": 15, "B": 10 } |
Requiring that A
is one of the items in B
We want to specify an enum for A
, and the values in that enum are contained in B
. Similarly to the numbers problem above, JSON Schema only allows for explicit lists for enum
, so we can’t source it from somewhere else.
1
2
3
4
5
6
7
8
9
10
{
"type": "object",
"properties": {
"A": { "enum": [ ??? ] },
"B": {
"type": "array",
"items": { "type": "string" }
}
}
}
We know that B
must be an array of strings, but how do we define that A
has to be one of the strings defined in B
?
Again, we need to define the keyword that needs the reference (enum
) inside a data
keyword and provide a plain JSON Pointer that points to where in the instance we want to get the values; in this case from the B
property.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"$schema": "https://json-everything.net/meta/data-2022",
"type": "object",
"properties": {
"A": {
"data": {
"enum": "/B"
}
},
"B": {
"type": "array",
"items": { "type": "string" }
}
}
}
Passes | Fails |
---|---|
{ "A": "cat", "B": [ "dog", "cat", "gerbil" ] } | { "A": "giraffe", "B": [ "dog", "cat", "gerbil" ] } |