C.W.K.
Stream
Lesson 01 of 08 · published

JSON Schema, In One Page

~12 min · json-schema, validation, draft-2020-12

Level 0Plaintext
0 XP0/64 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

A JSON document that describes the shape of other JSON documents

JSON Schema is itself JSON. You write a schema document, point a validator at a data document, and get back a 'valid' or a list of violations. The current dialect is Draft 2020-12 (informally just 'JSON Schema'). Earlier drafts (Draft-07, Draft-04) are still everywhere — read the $schema URI to know which.

Three things JSON Schema gives you

  • Validation — confirm a document matches a contract. Used at API edges, on config load, in CI.
  • IDE autocomplete — VS Code reads schemas from schemastore.org and gives you autocomplete + inline docs in package.json, tsconfig.json, .eslintrc.json, github-actions.yml, etc.
  • Documentation — schemas are docs. Tools like Redoc render OpenAPI schemas as a navigable site.

The smallest useful schema

'Any object with a string name' is enough to get a feel.

Principle: a schema is the place to encode invariants you'd otherwise enforce in code review. 'name is required, slug must match this regex, version follows semver' belongs in the schema, not in a wiki page nobody reads.

Code

Smallest useful schema·json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/user.schema.json",
  "title": "User",
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age":  { "type": "integer", "minimum": 0 }
  },
  "required": ["name"]
}
Validate from the shell (ajv-cli)·bash
# Install once
npm install -g ajv-cli

# Validate a document against a schema
ajv validate -s user.schema.json -d data.json

# Strict mode + draft 2020-12
ajv validate --strict=true --spec=draft2020 -s user.schema.json -d data.json
Validate from Python (jsonschema)·python
import json
from jsonschema import validate, ValidationError

schema = json.load(open('user.schema.json'))
data = json.load(open('data.json'))

try:
    validate(instance=data, schema=schema)
    print('valid')
except ValidationError as e:
    print(f'invalid: {e.message}')
    print(f'  at: {list(e.path)}')

External links

Exercise

Pick one of your project config files (tsconfig.json, package.json, an .eslintrc). Find its $schema URL — every popular config has one. Open the schema URL in a browser and read it as JSON. Notice how much of the autocomplete behavior in your editor is just JSON Schema doing its job.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.