Advanced JSON Schema Validation: Beyond the Basics
JSON Schema is a powerful vocabulary that allows you to annotate and validate JSON documents. Instead of writing ad-hoc validation functions scattered across your codebase, JSON Schema provides a declarative way to describe the structure, data types, constraints, and relationships within your JSON data. This guide covers everything from basic schema definitions to advanced validation patterns with practical examples. Use our JSON Schema Validator to test your schemas interactively.
What is JSON Schema?
JSON Schema defines the expected shape of a JSON document using JSON itself. A schema can specify: which properties are required, the expected data type of each field, minimum/maximum values, string pattern constraints, array length limits, and much more. Schemas follow the JSON Schema specification, currently at Draft 2020-12.
Basic Schema Structure
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/person.schema.json",
"title": "Person",
"description": "A person object",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"]
}
Common Validation Keywords
| Keyword | Applies To | Example | Description |
|---|---|---|---|
type | Any | "type": "string" | Must match the specified JSON type |
properties | Object | "properties": {"name": {...}} | Define individual property schemas |
required | Object | "required": ["name"] | List of properties that must be present |
minimum/maximum | Number | "minimum": 0 | Inclusive numeric bounds |
minLength/maxLength | String | "minLength": 1 | String length constraints |
pattern | String | "pattern": "^[a-zA-Z]+$" | Regex pattern match |
enum | Any | "enum": ["red", "green", "blue"] | Value must be one of the listed items |
format | String | "format": "email" | Semantic format validation |
minItems/maxItems | Array | "minItems": 1 | Array item count constraints |
additionalProperties | Object | "additionalProperties": false | Disallow properties not defined in properties |
String Formats
{
"format": "date" // YYYY-MM-DD
"format": "time" // HH:MM:SS[.Z]
"format": "date-time" // ISO 8601
"format": "email" // user@example.com
"format": "uri" // https://example.com
"format": "ipv4" // 192.168.1.1
"format": "uuid" // 550e8400-e29b-...
}
Array Validation Patterns
{
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
// Tuple validation
{
"type": "array",
"prefixItems": [
{"type": "string"},
{"type": "integer"},
{"type": "boolean"}
],
"minItems": 3,
"maxItems": 3
}
Conditional Validation with if/then/else
{
"type": "object",
"properties": {
"type": { "enum": ["individual", "business"] },
"companyName": { "type": "string" },
"personalName": { "type": "string" }
},
"if": {
"properties": { "type": { "const": "business" } },
"required": ["type"]
},
"then": { "required": ["companyName"] },
"else": { "required": ["personalName"] }
}
Validation in Code
JavaScript (Ajv)
import Ajv from 'ajv';
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(data);
if (!valid) console.log(validate.errors);
Python (jsonschema)
import jsonschema
jsonschema.validate(instance=data, schema=schema)
# Raises ValidationError on failure
Java (networknt)
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(
SpecVersionDetector.detect(schema));
JsonSchema jsonSchema = factory.getSchema(schema);
Set errors = jsonSchema.validate(data);
Schema Composition: allOf, anyOf, oneOf
{
"allOf": [
{"type": "object", "required": ["id"]},
{"properties": {"id": {"type": "integer"}}}
],
"anyOf": [
{"required": ["email"]},
{"required": ["phone"]}
],
"oneOf": [
{"required": ["personType", "firstName"]},
{"required": ["companyType", "companyName"]}
]
}
Recursive Schemas
{
"$id": "https://example.com/tree.schema.json",
"type": "object",
"properties": {
"value": {"type": "string"},
"children": {
"type": "array",
"items": {"$ref": "#"}
}
}
}
Best Practices
- Always define
$schemato specify which draft version you are using - Set
additionalProperties: falseto prevent unexpected fields - Use
requiredto document mandatory fields explicitly - Leverage
formatfor type-specific validation (email, URI, date-time) - Combine schemas with
allOf,anyOf,oneOffor complex constraints - Test your schemas with JSON Schema Validator
- Generate schemas from data with JSON Schema Generator
- Use JSON to Schema to create schemas from sample data
Next Steps
Test your schemas with our JSON Schema Validator. Generate schemas from sample data with JSON Schema Generator. Validate your data against schemas using JSON Validator.