Validate JSON Schema
How to validate JSON data against schemas in Python, Java, and JavaScript.
Note: This guide follows English-language naming conventions and terminology standards common in international development teams. Examples use English identifiers and comments to maximize compatibility across codebases and tooling.
Overview
JSON Schema defines the structure, types, and constraints of JSON data. It is the industry standard for validating API request bodies, configuration files, and inter-service messages. Implementing schema validation early catches malformed data before it reaches business logic, reducing bugs and security risks.
When to Use
Use this resource when:
- Validating REST API request payloads before processing
- Enforcing contracts between microservices via message schemas
- Validating user-generated configuration files at startup
- Generating TypeScript types, documentation, or OpenAPI specs from schemas
Solution
Python
# jsonschema is the most popular Python library
# pip install jsonschema
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"age": {"type": "integer", "minimum": 0},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "age", "email"]
}
try:
validate(instance={"name": "Ada", "age": 30, "email": "ada@example.com"}, schema=schema)
print("Valid")
except ValidationError as e:
print(f"Invalid: {e.message}")
JavaScript
// Ajv is the fastest JSON Schema validator for JavaScript
// npm install ajv
import Ajv from 'ajv';
const ajv = new Ajv({ allErrors: true });
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'integer', minimum: 0 },
email: { type: 'string', format: 'email' }
},
required: ['name', 'age', 'email']
};
const validate = ajv.compile(schema);
const valid = validate({ name: 'Ada', age: 30, email: 'ada@example.com' });
if (!valid) {
console.log(validate.errors);
}
Java
// networknt/json-schema-validator is a popular lightweight option
// Maven: com.networknt:json-schema-validator
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.ValidationMessage;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
JsonSchema schema = factory.getSchema("{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"}},\"required\":[\"name\"]}");
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree("{\"name\":\"Ada\"}");
Set<ValidationMessage> errors = schema.validate(node);
if (!errors.isEmpty()) {
errors.forEach(System.out::println);
}
Explanation
JSON Schema is specified by the JSON Schema Organization and supports drafts 04, 06, 07, 2019-09, and 2020-12. Core validation keywords include type, properties, required, minimum/maximum, pattern, enum, and format. Advanced features include $ref for composition, if/then/else for conditional schemas, and unevaluatedProperties for strict validation.
Most validators also support custom formats (email, uri, date-time) and user-defined vocabularies. Ajv additionally supports inline compilation to JavaScript functions for maximum performance.
Variants
| Technology | Library | Draft Support | Notes |
|---|---|---|---|
| Python | jsonschema | 04, 06, 07, 2019, 2020 | Most features, slightly slower |
| Python | fastjsonschema | 07, 2020 | Compiles to Python code, very fast |
| JavaScript | Ajv | 04, 06, 07, 2019, 2020 | Fastest JS validator, compiles schemas |
| JavaScript | zod | N/A (similar) | Type-first schemas, no JSON Schema required |
| Java | networknt | 04, 06, 07, 2019, 2020 | Lightweight, Jackson integration |
| Java | everit | 04, 06, 07 | Mature, strict compliance |
Best Practices
- Use strict mode (
additionalProperties: false) to reject unexpected fields and catch typos - Return all errors at once (
allErrors: truein Ajv) for better UX in forms - Version your schemas alongside API versions to avoid breaking changes
- Reuse definitions with
$refinstead of duplicating common sub-schemas - Keep schemas in
.jsonfiles under version control, not inline in code
Common Mistakes
- Using
type: "number"for integers: Usetype: "integer"when whole numbers are required - Missing
requiredarrays: Optional properties are the default; explicitly list required fields - Validating large files synchronously: Schema validation can block the event loop; use streams or worker threads
- Not pinning the draft version: Different validators default to different drafts; always specify
$schema - Ignoring format validation: Formats like
emailanddate-timemay be skipped by default; enable them explicitly
Frequently Asked Questions
Which JSON Schema draft should I use?
Draft 2020-12 is the latest stable version and is supported by Ajv, jsonschema, and networknt. Use it for new projects. Only use older drafts when integrating with legacy systems.
Can I generate TypeScript types from JSON Schema?
Yes. Tools like json-schema-to-typescript (npm) and QuickType generate TypeScript interfaces from schemas. Conversely, Zod and TypeBox let you define schemas as TypeScript types first.
How do I validate deeply nested objects efficiently?
Use $ref to modularize sub-schemas and enable compilation (Ajv compile(), fastjsonschema). For Python, fastjsonschema compiles schemas to Python code, offering 100x+ speedup over interpreted validation.