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

$ref and $defs — Reusable Fragments

~12 min · json-schema, ref, defs, reuse

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

Schemas grow; reuse keeps them sane

$defs — local definitions

$defs is a top-level dictionary of named sub-schemas. Define a shape once; reference it from anywhere in the same document with $ref. Replaces the older definitions keyword (Draft-07).

$ref — pointer to a schema

$ref takes a URI Reference. Same-document refs use a JSON Pointer fragment: #/$defs/Address. External-document refs use a full URL: https://example.com/address.schema.json. Most validators resolve external refs via HTTP fetch + cache, or via a 'load these schemas locally first' API.

$id — schemas that reference each other

Each schema document gets a stable $id URL. Other schemas reference it. The validator's job is to resolve $ids consistently — load all schemas you'll need into the validator before validating, and cross-references work transparently.

Principle: a schema is just JSON. Treat it like code — extract repeated shapes into $defs, name them well, reuse via $ref. The 50-line schema with three address objects copy-pasted is a refactor smell.

Code

$defs + $ref in one document·json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id":     "https://example.com/order.schema.json",
  "type":    "object",
  "properties": {
    "billing_address":  { "$ref": "#/$defs/Address" },
    "shipping_address": { "$ref": "#/$defs/Address" }
  },
  "required": ["billing_address"],
  "$defs": {
    "Address": {
      "type": "object",
      "properties": {
        "street":      { "type": "string" },
        "city":        { "type": "string" },
        "postal_code": { "type": "string" }
      },
      "required": ["street", "city", "postal_code"]
    }
  }
}
Cross-document $ref·json
{
  "$id":    "https://example.com/user.schema.json",
  "type":   "object",
  "properties": {
    "address": { "$ref": "https://example.com/address.schema.json" }
  }
}
Load schemas before validating (ajv example)·javascript
import Ajv from 'ajv/dist/2020.js';

const ajv = new Ajv();
ajv.addSchema(addressSchema);  // $id: .../address.schema.json
ajv.addSchema(userSchema);     // refers to address by $id

const validate = ajv.getSchema('https://example.com/user.schema.json');
const valid = validate(data);

External links

Exercise

Take a real schema you've written (or one you can find — e.g. a chunk of OpenAPI). Identify any shape repeated more than twice. Extract it into $defs/Name and replace the duplicates with $ref. Validate that the schema still works. The diff is your before/after illustration of why $defs exists.

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.