JSON Schema Validatiehandleiding: Valideer Je Datastructuur
Elke applicatie die data ontvangt van externe bronnen staat voor dezelfde fundamentele vraag: kan ik deze data vertrouwen? Of het nu een API request body is, een configuratiebestand, een bericht uit een queue, of een data-import, onvertrouwde data moet worden gevalideerd voordat het jouw systeem betreedt. JSON Schema biedt een gestandaardiseerde, taalonafhankelijke manier om te definiëren hoe geldige data eruitziet en om te verifiëren dat inkomende data aan die definitie voldoet. Deze handleiding behandelt alles, van het schrijven van je eerste schema tot geavanceerde patronen voor complexe validatie, met praktische voorbeelden die je direct kunt toepassen.
Wat is JSON Schema?
JSON Schema is een JSON-document dat de structuur en beperkingen van andere JSON-documenten beschrijft. Het is een vocabulaire waarmee je JSON-data kunt annoteren en valideren, gestandaardiseerd via de Internet Engineering Task Force (IETF). Een JSON Schema definieert regels over welke velden moeten bestaan, van welk type ze moeten zijn, welke waarden acceptabel zijn, en hoe objecten en arrays moeten worden gestructureerd.
Zie JSON Schema als een contract voor je data. Zoals een databaseschema de kolommen, typen en beperkingen van een tabel definieert, definieert een JSON Schema de eigenschappen, typen en beperkingen van een JSON-document. Elke JSON-data die aan alle beperkingen in een schema voldoet wordt een geldige instantie genoemd, terwijl data die een beperking schendt ongeldig is.
Wat JSON Schema Niet Is
- Geen dataformaat: JSON Schema definieert niet hoe data wordt geserialiseerd of verzonden. Het beschrijft alleen hoe geldige data eruitziet.
- Geen vervanging voor bedrijfslogica: Schemavalidatie controleert structurele correctheid (typen, formaten, bereiken). Complexe bedrijfsregels (zoals "een gebruiker kan niet meer overmaken dan zijn saldo") horen in applicatiecode thuis.
- Geen databaseschema: Hoewel de concepten vergelijkbaar zijn, valideert JSON Schema JSON-documenten, niet databasetabellen. Je kunt JSON Schema echter naast databasebeperkingen gebruiken voor defense in depth.
JSON Schema Versies
JSON Schema heeft zich ontwikkeld via verschillende drafts, die elk functies toevoegen en de vocabulaire verfijnen. Als je de versies begrijpt, kun je de juiste kiezen voor jouw project en compatibiliteitsproblemen vermijden.
| Versie | $schema URI | Status | Belangrijkste Functies |
|---|---|---|---|
| Draft 2020-12 | https://json-schema.org/draft/2020-12/schema | Huidig | prefixItems, dynamicRef, vocabulary support |
| Draft 2019-09 | https://json-schema.org/draft/2019-09/schema | Stabiel | unevaluatedProperties, $recursiveRef |
| Draft 7 | http://json-schema.org/draft-07/schema# | Breed ondersteund | if/then/else, contentEncoding |
| Draft 6 | http://json-schema.org/draft-06/schema# | Legacy | propertyNames, contains |
| Draft 4 | http://json-schema.org/draft-04/schema# | Verouderd | Oorspronkelijk breed toegepaste versie |
Je Eerste Schema Schrijven
Laten we beginnen met een eenvoudig voorbeeld: een schema voor een gebruikersobject met een naam, e-mail en leeftijd.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/user.json",
"title": "User",
"description": "A user account in the system",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "The user's full name"
},
"email": {
"type": "string",
"format": "email",
"description": "The user's email address"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150,
"description": "The user's age in years"
}
},
"required": ["name", "email"],
"additionalProperties": false
}Dit schema declareert dat een geldige gebruiker een object moet zijn met name en email als verplichte tekenreekseigenschappen. De eigenschap age is optioneel, maar moet een geheel getal tussen 0 en 150 zijn indien aanwezig. De additionalProperties: false beperking voorkomt eigenschappen die niet in het schema zijn gedefinieerd, wat typefouten en onverwachte velden opvangt.
Kernwoorden Referentie
JSON Schema biedt een rijke vocabulaire van sleutelwoorden voor het definiëren van beperkingen. Hier zijn de belangrijkste, georganiseerd per categorie.
Type Sleutelwoorden
| Sleutelwoord | Beschrijving | Voorbeeld |
|---|---|---|
| type | Verwachte datatype(n) | "type": "string" of "type": ["string", "null"] |
| enum | Lijst van toegestane waarden | "enum": ["active", "inactive", "pending"] |
| const | Moet exact aan deze waarde voldoen | "const": "v2" |
Getalbeperkingen
| Sleutelwoord | Beschrijving | Voorbeeld |
|---|---|---|
| minimum | Minimumwaarde (inclusief) | "minimum": 0 |
| exclusiveMinimum | Minimumwaarde (exclusief) | "exclusiveMinimum": 0 |
| maximum | Maximumwaarde (inclusief) | "maximum": 100 |
| exclusiveMaximum | Maximumwaarde (exclusief) | "exclusiveMaximum": 100 |
| multipleOf | Moet een veelvoud van deze waarde zijn | "multipleOf": 0.01 |
Tekenreeksbeperkingen
| Sleutelwoord | Beschrijving | Voorbeeld |
|---|---|---|
| minLength | Minimum tekenreekslengte | "minLength": 1 |
| maxLength | Maximum tekenreekslengte | "maxLength": 255 |
| pattern | Regex-patroon waaraan de tekenreeks moet voldoen | "pattern": "^[A-Z]{2}\\d{4}$" |
| format | Semantisch formaat (email, uri, date-time, enz.) | "format": "email" |
Objectbeperkingen
| Sleutelwoord | Beschrijving | Voorbeeld |
|---|---|---|
| properties | Schema voor elke bekende eigenschap | "properties": {"name": {"type": "string"}} |
| required | Lijst van verplichte eigenschappen | "required": ["name", "email"] |
| additionalProperties | Of extra eigenschappen zijn toegestaan | "additionalProperties": false |
| minProperties | Minimum aantal eigenschappen | "minProperties": 1 |
| maxProperties | Maximum aantal eigenschappen | "maxProperties": 10 |
| patternProperties | Schema's voor eigenschappen die aan een regex voldoen | "patternProperties": {"^S_": {"type": "string"}} |
Arraybeperkingen
| Sleutelwoord | Beschrijving | Voorbeeld |
|---|---|---|
| items | Schema voor alle array-items | "items": {"type": "string"} |
| prefixItems | Schema's voor positionele items (Draft 2020-12) | "prefixItems": [{"type": "string"}, {"type": "number"}] |
| minItems | Minimum aantal items | "minItems": 1 |
| maxItems | Maximum aantal items | "maxItems": 100 |
| uniqueItems | Alle items moeten uniek zijn | "uniqueItems": true |
Veelvoorkomende Schema Patronen
Schema's in de praktijk vereisen vaak patronen die verder gaan dan eenvoudige typecontrole. Hier zijn de meest voorkomende patronen.
Voorwaardelijke Validatie met if/then/else
Gebruik voorwaardelijke logica om verschillende beperkingen toe te passen op basis van de waarde van een eigenschap. Een betaalobject vereist bijvoorbeeld verschillende velden, afhankelijk van de betaalmethode.
{
"type": "object",
"properties": {
"method": { "enum": ["credit_card", "bank_transfer"] },
"card_number": { "type": "string" },
"routing_number": { "type": "string" }
},
"required": ["method"],
"if": {
"properties": { "method": { "const": "credit_card" } }
},
"then": {
"required": ["card_number"]
},
"else": {
"required": ["routing_number"]
}
}Compositie met allOf, anyOf, oneOf
Compositie-sleutelwoorden stellen je in staat schema's op krachtige manieren te combineren:
- allOf: Data moet aan ALLE sub-schema's voldoen. Gebruik dit om meerdere beperkingen te combineren of herbruikbare schema-fragmenten te mengen.
- anyOf: Data moet aan TEN MINSTE ÉÉN sub-schema voldoen. Gebruik dit voor union-types waarbij meerdere vormen acceptabel zijn.
- oneOf: Data moet aan PRECIES ÉÉN sub-schema voldoen. Gebruik dit voor wederzijds uitsluitende alternatieven.
{
"oneOf": [
{
"type": "object",
"properties": {
"type": { "const": "email" },
"address": { "type": "string", "format": "email" }
},
"required": ["type", "address"]
},
{
"type": "object",
"properties": {
"type": { "const": "phone" },
"number": { "type": "string", "pattern": "^\\+?[1-9]\\d{1,14}$" }
},
"required": ["type", "number"]
}
]
}Schema's Hergebruiken met $ref
Het $ref sleutelwoord stelt je in staat schema's te refereren en hergebruiken, wat duplicatie elimineert en je schema's onderhoudbaar houdt. Je kunt schema's binnen hetzelfde document of in externe bestanden refereren.
{
"$id": "https://example.com/schemas/order.json",
"type": "object",
"properties": {
"customer": { "$ref": "#/$defs/address" },
"shipping": { "$ref": "#/$defs/address" },
"billing": { "$ref": "#/$defs/address" },
"items": {
"type": "array",
"items": { "$ref": "#/$defs/lineItem" },
"minItems": 1
}
},
"required": ["customer", "items"],
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" },
"country": { "type": "string", "minLength": 2, "maxLength": 2 }
},
"required": ["street", "city", "zip", "country"]
},
"lineItem": {
"type": "object",
"properties": {
"product": { "type": "string" },
"quantity": { "type": "integer", "minimum": 1 },
"price": { "type": "number", "exclusiveMinimum": 0 }
},
"required": ["product", "quantity", "price"]
}
}
}Nullable Types
In JSON Schema Draft 2020-12 worden nullable types uitgedrukt met een array van typen die "null" omvat:
{
"type": ["string", "null"],
"description": "An optional display name, or null if not set"
}In oudere drafts werd het nullable: true sleutelwoord gebruikt in OpenAPI-specificaties. Voor standaard JSON Schema gebruik je altijd de type array-benadering.
Formaatvalidatie
Het format sleutelwoord biedt semantische validatie naast structurele controles. Het specificeert dat een tekenreeks aan een bekend formaat moet voldoen. Veelvoorkomende ondersteunde formaten zijn:
| Formaat | Beschrijving | Voorbeeld |
|---|---|---|
| E-mailadres | user@example.com | |
| uri | Geldige URI | https://example.com/path |
| uri-reference | URI of relatieve referentie | /path/to/resource |
| date-time | ISO 8601 date-time | 2026-05-19T14:30:00Z |
| date | ISO 8601 date | 2026-05-19 |
| time | ISO 8601 time | 14:30:00Z |
| ipv4 | IPv4-adres | 192.168.1.1 |
| ipv6 | IPv6-adres | ::1 |
| uuid | Universally unique identifier | 550e8400-e29b-41d4-a716-446655440000 |
| hostname | Internet hostname | www.example.com |
JSON Data Programmatisch Valideren
Schemavalidatie is het nuttigst wanneer het in je applicatiecode is geïntegreerd. Hier zijn voorbeelden met populaire libraries in verschillende talen.
JavaScript met Ajv
Ajv is de meest gebruikte JSON Schema validator voor JavaScript. Het ondersteunt alle draft-versies en biedt uitstekende prestaties door JIT-compilatie van schema's.
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
const ajv = new Ajv();
addFormats(ajv);
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 0 }
},
required: ['name', 'email'],
additionalProperties: false
};
const validate = ajv.compile(schema);
const valid = validate({ name: 'Alice', email: 'alice@example.com', age: 30 });
if (!valid) {
console.log(validate.errors);
// [{ keyword: 'required', params: { missingProperty: 'email' }, ... }]
}Python met jsonschema
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name", "email"],
"additionalProperties": False
}
try:
validate(instance={"name": "Alice", "email": "alice@example.com"}, schema=schema)
except ValidationError as e:
print(f"Validation failed: {e.message}")API Datavalidatie met JSON Schema
Een van de waardevolste toepassingen van JSON Schema is het valideren van API request- en response-data. Dit zorgt ervoor dat je API goed gevormde input ontvangt en data in het verwachte formaat teruggeeft, fouten vroegtijdig opvangt en duidelijke foutmeldingen aan clients levert.
Express.js Middleware
import Ajv from 'ajv';
const ajv = new Ajv({ allErrors: true });
function validateBody(schema) {
const validate = ajv.compile(schema);
return (req, res, next) => {
if (!validate(req.body)) {
return res.status(400).json({
error: 'Validation failed',
details: validate.errors
});
}
next();
};
}
app.post('/api/users',
validateBody({
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
email: { type: 'string', format: 'email' },
role: { enum: ['admin', 'editor', 'viewer'] }
},
required: ['name', 'email'],
additionalProperties: false
}),
(req, res) => {
// req.body is guaranteed valid here
createUser(req.body);
}
);OpenAPI en JSON Schema
OpenAPI (voorheen Swagger) gebruikt een subset van JSON Schema voor het definiëren van API request- en response-schema's. Als je al OpenAPI gebruikt, kun je de schema's uit je API-specificatie halen en gebruiken voor runtime-validatie. Tools zoals openapi-schema-validator en express-openapi-validator automatiseren dit proces, zodat je API-documentatie en validatielogica altijd gesynchroniseerd blijven.
Best Practices
- Stel altijd $schema in: Voeg het $schema sleutelwoord toe om te declareren welke draft je schema gebruikt. Dit voorkomt ambiguïteit en zorgt dat validators je schema correct interpreteren.
- Gebruik $id voor schema-identiteit: Het $id sleutelwoord biedt een unieke identifier voor je schema en dient als basis-URI voor het oplossen van $ref referenties. Stel het altijd in, zelfs voor lokale schema's.
- Stel additionalProperties: false in: JSON Schema staat standaard alle extra eigenschappen in objecten toe. Het instellen van additionalProperties: false vangt typefouten en onverwachte velden, waardoor je schema strikter wordt en je API voorspelbaarder.
- Gebruik $defs voor herbruikbare componenten: Definieer veelvoorkomende schema's in $defs en refereer ze met $ref. Dit vermindert duplicatie en maakt schema's beter onderhoudbaar.
- Voeg beschrijvingen toe: Elke eigenschap en elk schema moet een description-veld hebben. Dit dient als documentatie en helpt andere ontwikkelaars het doel en de beperkingen van elk veld te begrijpen.
- Valideer op systeemgrenzen: Pas schemavalidatie toe aan de randen van je systeem: API-eindpunten, message consumers, data-import pijplijnen en configuration loaders. Valideer geen data die je eigen code al heeft geproduceerd en vertrouwt.
- Schakel strict mode in validators in: Configureer je validator om onbekende sleutelwoorden te weigeren, formaatvalidatie af te dwingen en alle fouten te rapporteren in plaats van bij de eerste te stoppen. Dit vangt meer problemen in één validatieronde.
- Versieer je schema's: Voeg de schemaversie toe in de $id URI (bijv. https://example.com/schemas/user/v2.json). Hierdoor kun je schema's laten evolueren zonder bestaande consumers te breken.
- Test je schema's: Schrijf unit tests voor je schema's met zowel geldige als ongeldige voorbeelden. Dit zorgt dat je schema's de beperkingen afdwingt die je bedoelt en vangt regressies wanneer schema's worden gewijzigd.
- Gebruik format voor semantische validatie: Gebruik liever format: "email" dan een complex regex-patroon. Formaten zijn beter leesbaar, beter onderhoudbaar en profiteren van goed geteste validatielogica in je validator-library.
JSON-data tegen een schema willen valideren? Probeer onze gratis online JSON Schema Validator. Plak je schema en data om direct validatieresultaten te krijgen met gedetailleerde foutmeldingen.
JSON Schema ValidatorJSON FormatterVeelgestelde Vragen
Wat is JSON Schema?
JSON Schema is een JSON-document dat de structuur en beperkingen van andere JSON-documenten beschrijft. Het laat je verplichte velden, verwachte datatypen, waardebereiken, tekenreekspatronen en geneste objectstructuren definiëren. Je kunt het gebruiken om inkomende data te valideren, documentatie te genereren en form interfaces automatisch te maken.
Welke versie van JSON Schema moet ik gebruiken?
Gebruik JSON Schema Draft 2020-12 voor nieuwe projecten. Het is de meest recente stabiele versie en wordt ondersteund door grote validatiebibliotheken zoals Ajv. Draft 7 wordt ook breed ondersteund als je compatibiliteit met oudere tools nodig hebt. Vermijd Draft 4 en ouder, omdat deze verouderde sleutelwoorden gebruiken en moderne functies missen.
Hoe verschilt JSON Schema van TypeScript interfaces?
TypeScript interfaces bieden compile-time typecontrole, maar alleen binnen TypeScript-code. JSON Schema biedt runtime-validatie die werkt tussen programmeertalen en data van elke bron kan valideren (API-requests, bestanden, databases). Gebruik TypeScript voor veiligheid tijdens de ontwikkeling en JSON Schema voor runtime datavalidatie op systeemgrenzen.
Kan JSON Schema API request bodies valideren?
Ja, JSON Schema wordt veel gebruikt voor API request- en response-validatie. Frameworks zoals Express (met express-json-validator), FastAPI en Spring Boot ondersteunen JSON Schema-validatie direct of via middleware. Het valideren van request bodies tegen een schema zorgt ervoor dat inkomende data de juiste structuur heeft voordat je applicatie deze verwerkt.
Wat zijn de belangrijkste JSON Schema sleutelwoorden?
De meest essentiële sleutelwoorden zijn: type (datatype), properties (objectvelden), required (verplichte velden), items (array element schema), minimum/maximum (getalgrenzen), minLength/maxLength (tekenreeksgrenzen), pattern (regex voor tekenreeksen), enum (toegestane waarden) en $ref (referentie om schema's te hergebruiken). Deze dekken het overgrote deel van de validatiebehoeften.