The Complete Guide to JSON Schema Validation (Draft-07 & 2020-12)
An engineering manual for defining, validating, and testing robust JSON data contracts in modern APIs and distributed microservices.
1. Understanding JSON Schema Architecture
As distributed systems scale across microservices, mobile apps, and third-party webhooks, unstructured data becomes an operational liability. Without strict contract validation, an unexpected null value or mismatched type can crash downstream consumers.
JSON Schema solves this problem by defining a declarative, machine-readable vocabulary for annotating and validating JSON documents. By declaring schema expectations, teams can:
- Enforce strict API request and response contracts at the gateway boundary.
- Generate interactive API documentation (OpenAPI 3.1 natively uses JSON Schema).
- Automate property sanitization, default value assignment, and mock data generation.
- Prevent NoSQL injection and malicious payload tampering.
2. Anatomy of a Production JSON Schema
Below is a production-grade schema validating a User Account record using the latest Draft 2020-12 specification:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://api.example.com/schemas/user.json",
"title": "UserAccount",
"type": "object",
"required": ["id", "email", "role", "createdAt"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"username": {
"type": "string",
"minLength": 3,
"maxLength": 30,
"pattern": "^[a-zA-Z0-9_]+$"
},
"email": {
"type": "string",
"format": "email"
},
"role": {
"type": "string",
"enum": ["admin", "developer", "viewer"]
},
"age": {
"type": "integer",
"minimum": 18,
"maximum": 120
},
"tags": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true,
"maxItems": 10
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
} 3. Core Constraint Keywords Reference
| Target Type | Validation Keywords | Description & Use Case |
|---|---|---|
| Strings | minLength, maxLength, pattern, format | Enforces length boundaries, regex expressions, and RFC formats (email, uuid, date-time). |
| Numbers | minimum, maximum, multipleOf | Numeric ranges and divisibility (e.g., currency cents multipleOf: 0.01). |
| Objects | required, properties, additionalProperties, minProperties | Controls allowed keys and prevents accidental leaking of unexpected fields. |
| Arrays | items, minItems, maxItems, uniqueItems | Defines item schemas and prevents duplicate list entries. |
4. Validating JSON Schemas in Node.js with Ajv
Below is a complete, production-ready script executing high-performance schema validation in Node.js using ajv:
import Ajv from "ajv";
import addFormats from "ajv-formats";
const ajv = new Ajv({ allErrors: true, coerceTypes: false });
addFormats(ajv);
const userSchema = {
type: "object",
required: ["email", "role"],
properties: {
email: { type: "string", format: "email" },
role: { type: "string", enum: ["admin", "member"] }
}
};
const validate = ajv.compile(userSchema);
const incomingPayload = {
email: "[email protected]",
role: "admin"
};
if (validate(incomingPayload)) {
console.log("✅ Payload conforms strictly to contract.");
} else {
console.error("❌ Validation failed:", validate.errors);
}