Maintaining JSON Schema at Scale
Jason Desrosiers
Intro / Who am I
Treat Schemas as Code
Schema Identification and Referencing
Schema Identification and Referencing
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",�� "type": "object",� "properties": {� }�}
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "givenName": { "$ref": "#/$defs/name" },� "surname": { "$ref": "#/$defs/name" },� "address": { "$ref": "/schemas/address" }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 }� }�}
Schema Identification and Referencing
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",�� "type": "object",� "properties": {� }�}
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "givenName": { "$ref": "#/$defs/name" },� "surname": { "$ref": "#/$defs/name" },� "address": { "$ref": "/schemas/address" }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 }� }�}
Schema Identification and Referencing
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� <base href="https://example.com/schemas/address">�� "type": "object",� "properties": {� }�}
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� <base href="https://example.com/schemas/customer">�� "type": "object",� "properties": {� "givenName": { "$ref": <a href="#/$defs/name"> },� "surname": { "$ref": <a href="#/$defs/name"> },� "address": { "$ref": <a href="/schemas/address"> }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 }� }�}
Schema Identification and Referencing
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",�� "type": "object",� "properties": {� }�}
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "givenName": { "$ref": "#/$defs/name" },� "surname": { "$ref": "#/$defs/name" },� "address": { "$ref": "/schemas/address" }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 }� }�}
Schema Identification and Referencing
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/common",�� "$defs": {� "non-empty-string": {� "$anchor": "non-empty-string",� "type": "string",� "minimum": 1� }� }�}
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "givenName": {� "$ref": "/schemas/common#non-empty-string"� },� "surname": {� "$ref": "/schemas/common#non-empty-string"� },� "address": { "$ref": "/schemas/address" }� }�}
Schema Identification and Referencing
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/common",�� "$defs": {� "non-empty-string": {� <a id="non-empty-string"/>,� "type": "string",� "minimum": 1� }� }�}
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "givenName": {� "$ref": <a href="/schemas/common#non-empty-string"/>� },� "surname": {� "$ref": <a href="/schemas/common#non-empty-string"/>� },� "address": { "$ref": "/schemas/address" }� }�}
Schema Identification and Referencing
import JsonSchema from "@hyperjump/json-schema";��const customerSchema = JsonSchema.get("https://example.com/schemas/customer"); ❌ Not found�const isValid = JsonSchema.validate(customerSchema, customer).valid;
Schema Identification and Referencing
import JsonSchema from "@hyperjump/json-schema";��JsonSchema.add({ ... address schema ... });�JsonSchema.add({ ... customer schema ... });��const customerSchema = JsonSchema.get("https://example.com/schemas/customer"); ✅�const isValid = JsonSchema.validate(customerSchema, customer).valid;
Schema Identification and Referencing
📁 schemas� |- 🗎 address.schema.json� |- 🗎 customer.schema.json� |- 📁 nested� | - 🗎 another.schema.json
Schema Bundling
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "firstName": { "$ref": "#/$defs/name" },� "lastName": { "$ref": "#/$defs/name" },� "address": { "$ref": "/schemas/address" }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 },� "https://example.com/schemas/address": {� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",�� "type": "object",� "properties": {� "postalCode": { "$ref": "#/$defs/postalCode" }� },�� "$defs": {� "postalCode": { "pattern": "^[0-9]{5}(-[0-9]{4})?$" }� }� }� }�}
Schema Bundling
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "firstName": { "$ref": "#/$defs/name" },� "lastName": { "$ref": "#/$defs/name" },� "address": { "$ref": "/schemas/address" }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 },� "https://example.com/schemas/address": {� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",�� "type": "object",� "properties": {� "postalCode": { "$ref": "#/$defs/postalCode" }� },�� "$defs": {� "postalCode": { "pattern": "^[0-9]{5}(-[0-9]{4})?$" }� }� }� }�}
Schema Bundling
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "firstName": { "$ref": "#/$defs/name" },� "lastName": { "$ref": "#/$defs/name" },� "address": { "$ref": "/schemas/address" }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 },� "https://example.com/schemas/address": {� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",�� "type": "object",� "properties": {� "postalCode": { "$ref": "#/$defs/postalCode" }� },�� "$defs": {� "postalCode": { "pattern": "^[0-9]{5}(-[0-9]{4})?$" }� }� }� }�}
Schema Bundling
{� "components": {� "schemas": {� "Customer": {� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/customer",�� "type": "object",� "properties": {� "firstName": { "$ref": "#/$defs/name" },� "lastName": { "$ref": "#/$defs/name" },� "address": { "$ref": "/schemas/address" }� },�� "$defs": {� "name": { "type": "string", "minimum": 1, "maximum": 128 }� },� "Address": {� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",�� "type": "object",� "properties": {� "postalCode": { "$ref": "#/$defs/postalCode" }� },�� "$defs": {� "postalCode": { "pattern": "^[0-9]{5}(-[0-9]{4})?$" }� }� }� }� }�}
Code Style
Readable Schemas
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",� "type": "object",� "properties": {� "streetAddress": { "type": "string" },� "state": { "type": "string" },� "country": { "type": "string" }� },� "required": ["streetAddress"],� "if": {� "type": "object",� "properties": {� "country": { "const": "United States of America" }� },� "required": ["country"]� },� "then": { "required": ["state"] }�}
Readable Schemas
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",
"type": "object",� "properties": {� "streetAddress": { "type": "string"},� "state": { "type": "string" },� "country": { "type": "string" }� },� "required": ["streetAddress", "country"],� "allOf": [{ "$ref": "#/$defs/usa-requires-state" }],
"$defs":� "usa-requires-state": {� "if": {� "type": "object",� "properties": {� "country": { "const": "United States of America" }� },� "required": ["country"]� },� "then": { "required": ["state"] }� }� }�}
Readable Schemas
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",
"type": "object",� "properties": {� "streetAddress": { "type": "string"},� "state": { "type": "string" },� "country": { "type": "string" }� },� "required": ["streetAddress", "country"],� "allOf": [{ "$ref": "#/$defs/usa-requires-state" }],
"$defs":� "usa-requires-state": {� "if": {� "type": "object",� "properties": {� "country": { "const": "United States of America" }� },� "required": ["country"]� },� "then": { "required": ["state"] }� }� }�}
Readable Schemas
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",
"type": "object",� "properties": {� "streetAddress": { "type": "string"},� "state": { "type": "string" },� "country": { "type": "string" }� },� "required": ["streetAddress", "country"],� "allOf": [{ "$ref": "#/$defs/usa-requires-state" }],
"$defs":� "usa-requires-state": {� "if": {� "type": "object",� "properties": {� "country": { "const": "United States of America" }� },� "required": ["country"]� },� "then": { "required": ["state"] }� }� }�}
Readable Schemas
{� "$schema": "https://json-schema.org/draft/2020-12/schema",� "$id": "https://example.com/schemas/address",
"type": "object",� "properties": {� "streetAddress": { "type": "string"},� "state": { "type": "string" },� "country": { "type": "string" }� },� "required": ["streetAddress", "country"],� "allOf": [{ "$ref": "#/$defs/usa-requires-state" }],
"$defs":� "usa-requires-state": {� "if": {� "type": "object",� "properties": {� "country": { "const": "United States of America" }� },� "required": ["country"]� },� "then": { "required": ["state"] }� }� }�}
🚩Anti-patterns🚩
🚩oneOf🚩 - Union Types
🚩oneOf🚩 - Union Types
{� "oneOf": [� { "$ref": "#/$defs/car" },� { "$ref": "#/$defs/banana" },� { "$ref": "#/$defs/toaster" },� { "$ref": "#/$defs/wagon" },� { "$ref": "#/$defs/cellphone" },� { "$ref": "#/$defs/tshirt" },� { "$ref": "#/$defs/pillow" },� { "$ref": "#/$defs/sandals" },� { "$ref": "#/$defs/spoon" },� { "$ref": "#/$defs/rocket" },� { "$ref": "#/$defs/rope" },� { "$ref": "#/$defs/golfball" },� { "$ref": "#/$defs/dog" },� { "$ref": "#/$defs/mug" },� { "$ref": "#/$defs/boat" },� { "$ref": "#/$defs/peach" }� ],����
�������� "$defs": {� "car": {� "type": "object",� "properties": {� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["make", "model", "year"]� },�� "banana": {� "type": "object",� "properties": {� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["species", "color"]� },
🚩oneOf🚩 - Union Types
"oneOf": [� { "$ref": "#/$defs/car" },� { "$ref": "#/$defs/banana" }�],��"$defs": {� "car": {� "type": "object",� "properties": {� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["make", "model", "year"]� },�� "banana": {� "type": "object",� "properties": {� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["species", "color"]� }�}
{� make: "Subaru",� model: 42,� year: "2020"�}
❌ #/$defs/car/properties/model/type -> Value at `/model` must be a string, but a number was found.
❌ #/$defs/banana/required -> Value at `` is missing required properties "species" and "color".
🚩oneOf🚩 - Union Types
"oneOf": [� { "$ref": "#/$defs/car" },� { "$ref": "#/$defs/banana" }�],��"$defs": {� "car": {� "type": "object",� "properties": {� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["make", "model", "year"]� },�� "banana": {� "type": "object",� "properties": {� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["species", "color"]� }�}
{� make: "Subaru",� model: 42,� year: "2020"�}
❌ #/$defs/car/properties/model/type -> Value at `/model` must be a string, but a number was found.
❌ #/$defs/banana/required -> Value at `` is missing required properties "species" and "color".
🚩oneOf🚩 - Union Types
"oneOf": [� { "$ref": "#/$defs/car" },� { "$ref": "#/$defs/banana" }�],��"$defs": {� "car": {� "type": "object",� "properties": {� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["make", "model", "year"]� },�� "banana": {� "type": "object",� "properties": {� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["species", "color"]� }�}
{� make: "Subaru",� model: 42,� year: "2020"�}
❌ #/$defs/car/properties/model/type -> Value at `/model` must be a string, but a number was found.
❌ #/$defs/banana/required -> Value at `` is missing required properties "species" and "color".
🚩oneOf🚩 - Union Types
"components": {� "schemas": {� "Main": {� "discriminator": { "propertyName": "type" },� "oneOf": [� { "$ref": "#/components/schemas/car" },� { "$ref": "#/components/schemas/banana" }� ]� },�� "Car": {� "type": "object",� "properties": {� "type": { "const": "Car" },� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["type", "make", "model", "year"]� },�� "Banana": {� "type": "object",� "properties": {� "type": { "const": "Banana" },� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["type", "species", "color"]� }� }�}
{� type": "Car",� make: "Subaru",� model: 42,� year: "2020"�}
❌ #/components/schemas/Car/properties/model/type -> Value at `/model` must be a string, but a number was found.
🚩oneOf🚩 - Union Types
"components": {� "schemas": {� "Main": {� "discriminator": { "propertyName": "type" },� "oneOf": [� { "$ref": "#/components/schemas/car" },� { "$ref": "#/components/schemas/banana" }� ]� },�� "Car": {� "type": "object",� "properties": {� "type": { "const": "Car" },� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["type", "make", "model", "year"]� },�� "Banana": {� "type": "object",� "properties": {� "type": { "const": "Banana" },� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["type", "species", "color"]� }� }�}
{� type": "Car",� make: "Subaru",� model: 42,� year: "2020"�}
❌ #/components/schemas/Car/properties/model/type -> Value at `/model` must be a string, but a number was found.
✅ oneOf ✅ - Union Types
"allOf": [� {� "if": {� "type": "object",� "properties": { "type": { "const": "car" } },� "required": ["type"]� },� "then": { "$ref": "#/$defs/car" }� },� {� "if": {� "type": "object",� "properties": { "type": { "const": "banana" } },� "required": ["type"]� },� "then": { "$ref": "#/$defs/banana" }� }�],��"$defs": {� "car": {� "type": "object",� "properties": {� "type": { "const": "car" },� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["type", "make", "model", "year"]� },
{� "type": "car",� "make": "Subaru",� "model": 42,� "year": "2020"�}
❌ #/$defs/car/properties/model/type -> Value at `/model` must be a string, but a number was found.
�� "banana": {� "type": "object",� "properties": {� "type": { "const": "banana" },� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["type", "species", "color"]� }�}
✅ oneOf ✅ - Union Types
"allOf": [� {� "if": {� "type": "object",� "properties": { "type": { "const": "car" } },� "required": ["type"]� },� "then": { "$ref": "#/$defs/car" }� },� {� "if": {� "type": "object",� "properties": { "type": { "const": "car" } },� "required": ["type"]� },� "then": { "$ref": "#/$defs/banana" }� }�],��"$defs": {� "car": {� "type": "object",� "properties": {� "type": { "const": "car" },� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["type", "make", "model", "year"]� },
�� "banana": {� "type": "object",� "properties": {� "type": { "const": "banana" },� "species": { "type": "string" },� "color": { "type": "string" },� "nutrition": { "type": "string" }� },� "required": ["type", "species", "color"]� }�}
{� "type": "car",� "make": "Subaru",� "model": 42,� "year": "2020"�}
❌ #/$defs/car/properties/model/type -> Value at `/model` must be a string, but a number was found.
✅ oneOf ✅ - Mutually Exclusive Required Properties
✅ oneOf ✅ - Mutually Exclusive Required Properties
{� "oneOf": [� { "required": ["rock"] },� { "required": ["paper"] },� { "required": ["scissors"] }� ]�}
🚩additionalProperties🚩 - Polymorphism
🚩additionalProperties🚩 - Polymorphism
const cat: Cat = {� genus: "Felis",� species: "catus",� numberOfLives: 9�};��const dog: Dog = {� genus: "Canis",� species: "familiaris",� breed: "Labrador Retriever"�};��getScientificName(cat); // "Felis catus"�getScientificName(dog); // "Canis familiaris"
interface Animal {� genus: string;� species: string;�}��interface Cat extends Animal {� numberOfLives: number;�}��interface Dog extends Animal {� breed: string;�}��function getScientificName(a: Animal) {� return `${a.genus} ${a.species}`;�}
🚩additionalProperties🚩 - Polymorphism
{� "$id": "/schemas/animal",�� "type": "object",� "properties": {� "genus": { "type": "string" },� "species": { "type": "string" }� },� "required": ["genus", "species"]�}
{� "$id": "/schemas/cat",�� "$ref": "/schemas/animal",� "properties": {� "numberOfLives": { "type": "integer" }� },� "required": ["numberOfLives"]�}�
🚩additionalProperties🚩 - Polymorphism
{� "$id": "/schemas/animal",�� "type": "object",� "properties": {� "genus": { "type": "string" },� "species": { "type": "string" }� },� "required": ["genus", "species"],� "additionalProperties": false�}
{� "$id": "/schemas/cat",�� "$ref": "/schemas/animal",� "properties": {� "numberOfLives": { "type": "integer" }� },� "required": ["numberOfLives"]�}�
🚩additionalProperties🚩 - Polymorphism
{� "$id": "/schemas/animal",�� "type": "object",� "properties": {� "genus": { "type": "string" },� "species": { "type": "string" }� },� "required": ["genus", "species"]�}
{� "$id": "/schemas/cat",�� "$ref": "/schemas/animal",� "properties": {� "numberOfLives": { "type": "integer" }� },� "required": ["numberOfLives"],� "additionalProperties": false�}�
✅ additionalProperties ✅ - Polymorphism
{� "$id": "/schemas/animal",�� "type": "object",� "properties": {� "genus": { "type": "string" },� "species": { "type": "string" }� },� "required": ["genus", "species"]�}
{� "$id": "/schemas/cat",�� "$ref": "/schemas/animal",� "properties": {� "numberOfLives": { "type": "integer" }� },� "required": ["numberOfLives"],� "unevaluatedProperties": false�}�
✅ additionalProperties ✅ - Polymorphism
{� "$id": "/schemas/animal",�� "type": "object",� "properties": {� "genus": { "type": "string" },� "species": { "type": "string" }� },� "required": ["genus", "species"],�� "$defs": {� "strict": {� "$anchor": "strict",� "$ref": "#",� "unevaluatedProperties": false� }� }�}
✅ additionalProperties ✅ - Polymorphism
{� "$id": "/schemas/animal",�� "type": "object",� "properties": {� "genus": { "type": "string" },� "species": { "type": "string" }� },� "required": ["genus", "species"],�� "$defs": {� "strict": {� "$anchor": "strict",� "$ref": "#",� "unevaluatedProperties": false� }� }�}
🚩additionalProperties🚩 - Object Maps
🚩additionalProperties🚩 - Object Maps
{� "type": "object",� "properties": {� "event": { "type": "string" },� "level": { "type": "string" },� "scores": {� "type": "object",� "additionalProperties": {� "type": "number"� }� }� }�}
{� "event": "Uneven Bars",� "level": "5",� "scores": {� "Milana": 9.5,� "Alexis": 9.3,� "Angelina": 9.7,� "Loraine": 8.9� }�}
🚩additionalProperties🚩 - Object Maps
{� "type": "object",� "properties": {� "event": { "type": "string" },� "level": { "type": "string" },� "scores": {� "type": "object",� "patternProperties": {� "\\*$": { "minimum": 9.0 }� },� "additionalProperties": {� "type": "number"� }� }� }�}
{� "event": "Uneven Bars",� "level": "5",� "scores": {� "Milana*": 9.5,� "Alexis*": 9.3,� "Angelina*": 9.7,� "Loraine": 8.9� }�}
🚩additionalProperties🚩 - Object Maps
{� "type": "object",� "properties": {� "event": { "type": "string" },� "level": { "type": "string" },� "scores": {� "type": "object",� "patternProperties": {� "\\*$": { "minimum": 9.0 }� },� "additionalProperties": {� "type": "number"� }� }� }�}
{� "event": "Uneven Bars",� "level": "5",� "scores": {� "Milana*": "9.5",� "Alexis*": 9.3,� "Angelina*": 9.7,� "Loraine": 8.9� }�}
✅ additionalProperties ✅ - Object Maps
{� "type": "object",� "properties": {� "event": { "type": "string" },� "level": { "type": "string" },� "scores": {� "type": "object",� "patternProperties": {� "": { "type": "number" },� "\\*$": { "minimum": 9.0 }� }� }� }�}
{� "event": "Uneven Bars",� "level": "5",� "scores": {� "Milana*": 9.5,� "Alexis*": 9.3,� "Angelina*": 9.7,� "Loraine": 8.9� }�}
Template Schema Pattern
Template Schema Pattern - Dynamic References
{� "$id": "/schemas/extended",�� "$ref": "/schemas/base",� "properties": {� "bbb": { "$ref": "#foo" }� },�� "$defs": {� "foo": {� "$anchor": "foo",� "type": "number"� }� }�}
{� "$id": "/schemas/base",�� "type": "object",� "properties": {� "aaa": { "$ref": "#foo" }� },�� "$defs": {� "foo": {� "$anchor": "foo",� "type": "string"� }� }�}
Template Schema Pattern - Dynamic References
{� "$id": "/schemas/extended",�� "$ref": "/schemas/base",� "properties": {� "bbb": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "number"� }� }�}
{� "$id": "/schemas/base",�� "type": "object",� "properties": {� "aaa": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "string"� }� }�}
Template Schema Pattern - Dynamic References
{� "$id": "/schemas/extended",�� "$ref": "/schemas/base",� "properties": {� "bbb": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "number"� }� }�}
{� "$id": "/schemas/base",�� "type": "object",� "properties": {� "aaa": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "string"� }� }�}
Template Schema Pattern - Dynamic References
{� "$id": "/schemas/extended",�� "$ref": "/schemas/base",� "properties": {� "bbb": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "number"� }� }�}
{� "$id": "/schemas/base",�� "type": "object",� "properties": {� "aaa": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "string"� }� }�}
Template Schema Pattern - Dynamic References
{� "$id": "/schemas/extended",�� "$ref": "/schemas/base",� "properties": {� "bbb": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "number"� }� }�}
{� "$id": "/schemas/base",�� "type": "object",� "properties": {� "aaa": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "string"� }� }�}
Template Schema Pattern - Dynamic References
{� "$id": "/schemas/extended",�� "$ref": "/schemas/base",� "properties": {� "bbb": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "number"� }� }�}
{� "$id": "/schemas/base",�� "type": "object",� "properties": {� "aaa": { "$dynamicRef": "#foo" }� },�� "$defs": {� "foo": {� "$dynamicAnchor": "foo",� "type": "string"� }� }�}
Template Schema Pattern - List
{� "$id": "/schemas/car",�� "type": "object",� "properties": {� "make": { "type": "string" },� "model": { "type": "string" },� "year": { "type": "string" }� },� "required": ["make", "model", "year"]�}
{� "$id": "/schema/car-list",�� "type": "object",� "properties": {� "listItems": {� "type": "array",� "items": { "$ref": "/schema/car" }� },� "nextPage": { "type": "integer" },� "prevPage": { "type": "integer" },� "perPage": { "type": "integer" },� "page": { "type": "integer" }� }�}
Template Schema Pattern - List
{� "$id": "/schema/car-list",�� "$ref": "/schema/list",� "properties": {� "listItems": {� "items": { "$ref": "/schema/car" }� }� }�}
{� "$id": "/schema/list",�� "type": "object",� "properties": {� "listItems": { "type": "array" },� "nextPage": { "type": "integer" },� "prevPage": { "type": "integer" },� "perPage": { "type": "integer" },� "page": { "type": "integer" }� }�}
Template Schema Pattern - List
{� "$id": "/schema/car-list",�� "$ref": "/schema/list",� "properties": {� "listItems": {� "items": { "$ref": "/schema/car" }� }� }�}
{� "$id": "/schema/list",�� "type": "object",� "properties": {� "listItems": { "type": "array" },� "nextPage": { "type": "integer" },� "prevPage": { "type": "integer" },� "perPage": { "type": "integer" },� "page": { "type": "integer" }� }�}
Template Schemas Pattern - List
{� "$id": "/schema/car-list",�� "$ref": "/schema/list",�� "$defs": {� "list-items": {� "$dynamicAnchor": "list",� "$ref": "/schema/car"� }� }�}
{� "$id": "/schema/list",�� "type": "object",� "properties": {� "listItems": {� "type": "array",� "items": { "$dynamicRef": "#list" }� },� "nextPage": { "type": "integer" },� "prevPage": { "type": "integer" },� "perPage": { "type": "integer" },� "page": { "type": "integer" }� },�� "$defs": {� "default-list-item": {� "$dynamicAnchor": "list"� }� }�}
Template Schemas Pattern - List
{� "$id": "/schema/car-list",�� "$ref": "/schema/list",�� "$defs": {� "list-items": {� "$dynamicAnchor": "list",� "$ref": "/schema/car"� }� }�}
{� "$id": "/schema/list",�� "type": "object",� "properties": {� "listItems": {� "type": "array",� "items": { "$dynamicRef": "#list" }� },� "nextPage": { "type": "integer" },� "prevPage": { "type": "integer" },� "perPage": { "type": "integer" },� "page": { "type": "integer" }� },�� "$defs": {� "default-list-item": {� "$dynamicAnchor": "list"� }� }�}
Template Schemas Pattern - List
{� "$id": "/schema/car-list",�� "$ref": "/schema/list",�� "$defs": {� "list-items": {� "$dynamicAnchor": "list",� "$ref": "/schema/car"� }� }�}
{� "$id": "/schema/list",�� "type": "object",� "properties": {� "listItems": {� "type": "array",� "items": { "$dynamicRef": "#list" }� },� "nextPage": { "type": "integer" },� "prevPage": { "type": "integer" },� "perPage": { "type": "integer" },� "page": { "type": "integer" }� },�� "$defs": {� "default-list-item": {� "$dynamicAnchor": "list"� }� }�}
Template Schemas Pattern - List
{� "$id": "/schema/car-list",�� "$ref": "/schema/list",�� "$defs": {� "list-items": {� "$dynamicAnchor": "list",� "$ref": "/schema/car"� }� }�}
{� "$id": "/schema/list",�� "type": "object",� "properties": {� "listItems": {� "type": "array",� "items": { "$dynamicRef": "#list" }� },� "nextPage": { "type": "integer" },� "prevPage": { "type": "integer" },� "perPage": { "type": "integer" },� "page": { "type": "integer" }� },�� "$defs": {� "default-list-item": {� "$dynamicAnchor": "list"� }� }�}
Cheatsheet
References
Jason Desrosiers
jason@hyperjump.io
https://github.com/jdesrosiers
@jasondesrosiers