JSON Schema basics: a standard for validating data shape
JSON Schema is the standard for defining and validating the shape of JSON data. It powers OpenAPI specs, editor autocomplete for config files, and a lot of API request validation. This article walks through the core keywords and the pitfalls.
What it is
JSON Schema is a spec (IETF Draft) for describing JSON data using JSON.
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 }
},
"required": ["name"]
} Against this schema, { "name": "Alice", "age": 30 } is valid; { "age": -5 } is invalid (missing name, negative age).
Core keywords
type
{ "type": "string" }
{ "type": "integer" }
{ "type": "number" }
{ "type": "boolean" }
{ "type": "array" }
{ "type": "object" }
{ "type": "null" } Multiple types:
{ "type": ["string", "null"] } Object properties
{
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"],
"additionalProperties": false
} Without additionalProperties: false, unknown keys pass through silently. Forgetting it is a common bug source.
Arrays
{
"type": "array",
"items": { "type": "integer" },
"minItems": 1,
"maxItems": 100
} String constraints
{
"type": "string",
"minLength": 3,
"maxLength": 50,
"pattern": "^[A-Z][a-z]+$",
"format": "email"
} format recognizes email, uri, date-time, uuid, and so on. Validators differ on how strictly they enforce these.
Number constraints
{
"type": "integer",
"minimum": 0,
"maximum": 100,
"exclusiveMinimum": 0
} Beyond the basics
enum
{ "enum": ["red", "green", "blue"] } Works for any value type, not just strings.
oneOf / anyOf / allOf
{
"oneOf": [{ "type": "string" }, { "type": "integer" }]
} oneOf— matches exactly oneanyOf— matches at least oneallOf— matches all
$ref for reuse
{
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" }
}
}
},
"type": "object",
"properties": {
"shipping": { "$ref": "#/$defs/address" },
"billing": { "$ref": "#/$defs/address" }
}
} Reuse common shapes via $ref. OpenAPI puts these under components.schemas and references them across paths.
Where it shows up
1. API specs (OpenAPI / Swagger)
OpenAPI uses JSON Schema for request/response shapes, enabling docs, mock servers, and client generation.
2. Config files
VS Code, ESLint, Prettier publish JSON Schemas; editors use them for autocomplete and inline validation.
3. Form / request validation
On the server, libraries like Ajv accept a JSON Schema and validate incoming bodies against it.
4. Database constraints
Postgres JSONB columns can enforce a JSON Schema via a CHECK constraint.
Common traps
1. Forgetting additionalProperties
{
"properties": {
"name": { "type": "string" }
}
} This says “if name exists it must be a string”. Unknown keys pass without complaint. Set additionalProperties: false for strict shapes.
2. integer vs number
number accepts floats; integer accepts whole numbers. Validators disagree on how to handle 1.0 against integer.
3. format enforcement varies
format: "email" regex differs across validators. For real email validation, use a dedicated library.
4. Nullable representations differ
OpenAPI 3.0 uses nullable: true; pure JSON Schema uses type: ["string", "null"]. Don’t mix them.
Summary
- JSON Schema describes JSON shape in JSON.
- Core keywords:
type,properties,required,additionalProperties. $reffor reuse;oneOf,anyOf,allOffor combinations.- Used in API specs, config files, form validation.
To check that JSON conforms to a schema, the JSON validator on this site accepts both inputs and reports mismatches.