What Is JSON Schema?
JSON Schema is a declarative language for defining the structure, content, and constraints of JSON data. Think of it as a blueprint that describes what valid JSON looks like for your application. It is used for API request/response validation, form generation, configuration file validation, and documentation.
Your First JSON Schema
Suppose you have a user object:
{
"name": "Alice",
"email": "alice@example.com",
"age": 30
}
Here is a JSON Schema that validates this structure:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "User",
"description": "A registered user in the system",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
}
},
"required": ["name", "email"],
"additionalProperties": false
}
Core Schema Types
JSON Schema supports these primitive types:
| Type | Description | Example |
|---|---|---|
string |
Text values | "hello" |
number |
Any numeric value | 3.14 |
integer |
Whole numbers only | 42 |
boolean |
True or false | true |
null |
Null value | null |
array |
Ordered list | [1, 2, 3] |
object |
Key-value pairs | {"key": "value"} |
String Validation
{
"type": "string",
"minLength": 1,
"maxLength": 255,
"pattern": "^[A-Z][a-z]+$",
"format": "email"
}
Common formats: email, uri, date, date-time, ipv4, ipv6, uuid, hostname.
Array Validation
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
For tuple validation (fixed-length arrays with typed positions):
{
"type": "array",
"prefixItems": [
{ "type": "number" },
{ "type": "string" },
{ "type": "boolean" }
],
"items": false
}
This matches [42, "hello", true] but rejects [42, "hello", true, "extra"].
Composition Keywords
oneOf, anyOf, allOf
{
"oneOf": [
{
"type": "object",
"properties": {
"type": { "const": "email" },
"address": { "type": "string", "format": "email" }
},
"required": ["type", "address"]
},
{
"type": "object",
"properties": {
"type": { "const": "phone" },
"number": { "type": "string", "pattern": "^[+]?[0-9]{10,15}$" }
},
"required": ["type", "number"]
}
]
}
This validates either an email contact or a phone contact, but not both.
Reusable Schemas with $ref
The $ref keyword lets you reference and reuse schema definitions:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Order",
"type": "object",
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^[0-9]{5}$" }
},
"required": ["street", "city", "zip"]
},
"product": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"price": { "type": "number", "minimum": 0 }
},
"required": ["id", "name", "price"]
}
},
"properties": {
"shipping_address": { "$ref": "#/$defs/address" },
"billing_address": { "$ref": "#/$defs/address" },
"items": {
"type": "array",
"items": { "$ref": "#/$defs/product" },
"minItems": 1
},
"total": { "type": "number", "minimum": 0 }
},
"required": ["shipping_address", "items", "total"]
}
Validation in Node.js with Ajv
Ajv is the most popular JSON Schema validator for JavaScript:
npm install ajv ajv-formats
const Ajv = require('ajv');
const addFormats = require('ajv-formats');
const ajv = new Ajv({ allErrors: true });
addFormats(ajv);
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 0 },
tags: {
type: 'array',
items: { type: 'string' },
uniqueItems: true
}
},
required: ['name', 'email'],
additionalProperties: false
};
const validate = ajv.compile(schema);
// Valid data
const validUser = { name: 'Alice', email: 'alice@example.com', age: 30 };
console.log(validate(validUser)); // true
// Invalid data
const invalidUser = { name: '', email: 'not-an-email', age: -5 };
console.log(validate(invalidUser)); // false
console.log(validate.errors);
// [
// { keyword: 'minLength', instancePath: '/name', ... },
// { keyword: 'format', instancePath: '/email', ... },
// { keyword: 'minimum', instancePath: '/age', ... }
// ]
Express Middleware Example
function validateBody(schema) {
const validate = ajv.compile(schema);
return (req, res, next) => {
if (!validate(req.body)) {
return res.status(400).json({
error: 'Validation failed',
details: validate.errors.map(err => ({
field: err.instancePath,
message: err.message
}))
});
}
next();
};
}
app.post('/api/users', validateBody(userSchema), (req, res) => {
// req.body is guaranteed to be valid here
res.json({ message: 'User created', user: req.body });
});
Validation in Python with jsonschema
pip install jsonschema
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"email": {"type": "string", "format": "email"},
"scores": {
"type": "array",
"items": {"type": "number", "minimum": 0, "maximum": 100}
}
},
"required": ["name", "email"],
"additionalProperties": False
}
# Valid data
valid_data = {"name": "Alice", "email": "alice@example.com", "scores": [95, 87, 92]}
validate(instance=valid_data, schema=schema)
print("Validation passed!")
# Invalid data
try:
invalid_data = {"name": "", "email": "bad", "scores": [101]}
validate(instance=invalid_data, schema=schema)
except ValidationError as e:
print(f"Validation error: {e.message}")
print(f"Path: {list(e.absolute_path)}")
Conditional Schemas
Use if/then/else for conditional validation:
{
"type": "object",
"properties": {
"payment_method": { "enum": ["credit_card", "bank_transfer"] },
"card_number": { "type": "string" },
"routing_number": { "type": "string" }
},
"if": {
"properties": { "payment_method": { "const": "credit_card" } }
},
"then": {
"required": ["card_number"]
},
"else": {
"required": ["routing_number"]
}
}
Generate Schemas Instantly
Writing JSON Schemas by hand can be tedious. Use the DevToolBox JSON Schema Generator to paste any JSON sample and automatically generate a complete JSON Schema with proper types, required fields, and validation constraints.
Top comments (0)