Validation against allOf subschemas
In JSON Schema you can add multiple reusable subschemas to your keyword, and then ensure that all conditions from all reusable subschemas are met. You can do it by using allOf keyword.
{
"$defs": {
"ageLimit": {
"minimum": 18,
"maximum": 50
}
},
"type": "object",
"properties": {
"age": {
"type": "integer",
"allOf": {
{"$ref": "#/$defs/ageLimit"}
{"$ref": "https://example.com/person"}
}
}
}
} In the example above, we say that age keyword needs to be an integer, but that it also needs to have age limit between 18 and 50.
Validation against oneOf subschemas
You can validate your properties in a schema using exactly one of the schema definitions. That means, if one of the schema defs is valid, the whole thing is valid.
{
"type": "object",
"properties": {
"age": {
"type": "integer"
"oneOf": [
{
"minimum": 18,
"aximum": 60,
},
{
"minimum": 65
}
]
}
}
} In the example above, we apply condition to the age and age will be valid based on one of these conditions:
- When age is >= 18 and ⇐ 60
- When age is >= 65
Inverting Validation
You can invert validation using not keyword. This is useful when properties are between values, but there’s one value in that range that you want to exclude from it
{
"type": "object",
"properties": {
"age": {
"type": "integer",
"minimum": 18,
"not": {"const": 21}
}
}
} In the example above, we do not allow age of 21, but any other age from age of 18 (inclusive) is valid.
Recursive Schemas
in JSON Schema, you can create schemas that refer to themselves recursively. It is useful when modelling hierarchical data structures or creating recursive relationships.
{
"$defs": {
"next": {
"type": "object",
"properties": {
"value": {
"type": "string"
},
"next": {
"oneOf": [
{
"$ref": "#/$defs/next"
},
{
"type": "null"
}
]
}
},
"required": [
"value",
"next"
]
}
},
"type": "object",
"properties": {
"name": {
"type": "string"
},
"next": {
"$ref": "#/$defs/next"
}
}
} Extending Closed Schemas
You can use unevaluatedProperties key in your schema to allow you to create complicated schemas. It works by collecting properties that are successfully validated when processing the schemas and using those as the allowed list of properties.
In this schema, the properties declared in the then schema only count as “evaluated” properties if the “type” of the address is “business”.
{
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" },
"type": { "enum": ["residential", "business"] }
},
"required": ["street_address", "city", "state", "type"],
"if": {
"type": "object",
"properties": {
"type": { "const": "business" }
},
"required": ["type"]
},
"then": {
"properties": {
"department": { "type": "string" }
}
},
"unevaluatedProperties": false
} {
"street_address": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"type": "business",
"department": "HR"
}
// Correct {
"street_address": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"type": "residential",
"department": "HR"
}
// Incorrect Default
You can set a default value for a property using default keyword
{
"type": "string",
"default": "Oskar"
}