JSON Schema: What It Is and How to Use It
Learn JSON Schema from scratch. Understand types, constraints, composition keywords, $ref, and see a complete practical example for API validation.
Was ist JSON Schema?
JSON Schema ist ein Vokabular, mit dem Sie die Struktur von JSON-Daten beschreiben können. Denken Sie daran wie an einen Vertrag: Es definiert, welche Felder ein JSON-Dokument haben sollte, welche Typen diese Felder haben müssen und welche Einschränkungen sie erfüllen müssen. Wenn ein Dokument seinem Schema entspricht, ist es gültig. Wenn nicht, sagt Ihnen ein Validator genau, was schiefgelaufen ist.
Das ist wichtig, weil JSON selbst strukturell permissiv ist. Nichts in der JSON-Spezifikation hindert eine API daran, einen String zurückzugeben, wo Sie eine Zahl erwarten, oder ein erforderliches Feld wegzulassen. JSON Schema schließt diese Lücke.
Warum JSON Schema wichtig ist
- API-Verträge. Definieren Sie genau, was Ihre API erwartet und zurückgibt. Sowohl Client- als auch Serverseiten-Teams können Payloads unabhängig validieren.
- Datenvalidierung. Fangen Sie fehlerhafte Daten an der Grenze ab — bei Formularübermittlungen, Webhook-Payloads, Konfigurationsdateien oder Datenbankeinträgen.
- Dokumentation. Ein Schema ist maschinenlesbare Dokumentation. Tools können daraus menschenlesbare Dokumente, Formulare und sogar Mock-Daten generieren.
- Code-Generierung. Generieren Sie TypeScript-Interfaces, Go-Structs oder Python-Datenklassen direkt aus Ihrem Schema.
Die Grundlagen: Typ, Eigenschaften, Erforderlich
Jedes JSON Schema beginnt mit type. Dies sagt dem Validator, welche Art von Wert auf der obersten Ebene erwartet wird:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Der vollständige Name des Benutzers"
},
"age": {
"type": "integer",
"description": "Alter in Jahren"
}
},
"required": ["name"]
}
Dieses Schema sagt: "Ich erwarte ein JSON-Objekt mit einer name-Eigenschaft (String, erforderlich) und einer optionalen age-Eigenschaft (Integer)." Jedes Objekt, das name fehlt oder einen nicht-String name bereitstellt, ist ungültig.
Alle JSON Schema Typen
JSON Schema unterstützt sieben primitive Typen. Hier ist jeder mit einem minimalen Schema-Beispiel:
| Typ | Gültige Werte | Schema-Beispiel |
|---|---|---|
string | "hallo", "" | {"type": "string"} |
number | 3.14, -1, 0 | {"type": "number"} |
integer | 42, -7 | {"type": "integer"} |
boolean | true, false | {"type": "boolean"} |
null | null | {"type": "null"} |
object | {"key": "value"} | {"type": "object", "properties": {...}} |
array | [1, 2, 3] | {"type": "array", "items": {...}} |
Objekte im Detail
Verwenden Sie properties, um erwartete Felder zu definieren, required, um obligatorische aufzulisten, und additionalProperties, um zu steuern, ob zusätzliche Felder erlaubt sind:
{
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string", "format": "email" }
},
"required": ["id", "email"],
"additionalProperties": false
}
Das Setzen von additionalProperties: false weist jedes Objekt zurück, das Schlüssel enthält, die nicht in properties aufgeführt sind. Dies ist nützlich für strenge API-Verträge.
Arrays im Detail
Verwenden Sie items, um zu definieren, wie jedes Element aussehen sollte, und minItems / maxItems, um die Länge einzuschränken:
{
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
Dies akzeptiert ein Array von 1 bis 10 einzigartigen Strings. Ein leeres Array oder ein Array mit Duplikaten würde die Validierung nicht bestehen.
Einschränkungen und Validierungs-Schlüsselwörter
Über die grundlegenden Typen hinaus bietet JSON Schema feingranulare Einschränkungen für jeden Typ:
String-Einschränkungen
| Schlüsselwort | Beschreibung | Beispiel |
|---|---|---|
minLength | Mindestanzahl an Zeichen | "minLength": 1 |
maxLength | Höchstanzahl an Zeichen | "maxLength": 255 |
pattern | Regex, dem der String entsprechen muss | "pattern": "^[A-Z]{2}\\\\d{4}$" |
format | Semantischer Format-Hinweis | "format": "email" |
enum | Erlaubte Werte | "enum": ["aktiv", "inaktiv"] |
Zahlen-Einschränkungen
| Schlüsselwort | Beschreibung | Beispiel |
|---|---|---|
minimum | Wert muss >= diesem sein | "minimum": 0 |
maximum | Wert muss <= diesem sein | "maximum": 100 |
exclusiveMinimum | Wert muss > diesem sein | "exclusiveMinimum": 0 |
exclusiveMaximum | Wert muss < diesem sein | "exclusiveMaximum": 1000 |
multipleOf | Wert muss durch diesen teilbar sein | "multipleOf": 0.01 |
Kombination von Schemata: allOf, anyOf, oneOf, not
Zusammensetzungs-Schlüsselwörter ermöglichen es Ihnen, komplexe Schemata aus einfacheren zu erstellen:
- allOf — Die Daten müssen gegen alle aufgeführten Schemata gültig sein. Wird verwendet, um mehrere Einschränkungen zu kombinieren oder ein Basisschema zu erweitern.
- anyOf — Die Daten müssen gegen mindestens eines der aufgeführten Schemata gültig sein. Nützlich für Felder, die mehrere Formate akzeptieren.
- oneOf — Die Daten müssen gegen genau eines der aufgeführten Schemata gültig sein. Gut für diskriminierte Vereinigungen.
- not — Die Daten dürfen nicht gegen das angegebene Schema gültig sein.
{
"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": "^\\\\+?[0-9]{7,15}$" }
},
"required": ["type", "number"]
}
]
}
Dieses Schema akzeptiert entweder einen E-Mail-Kontakt oder einen Telefonkontakt, aber nicht beide — eine saubere Möglichkeit, getaggte Vereinigungen zu modellieren.
Wiederverwendbarkeit mit $ref
Schemata werden schnell repetitiv. Der $ref-Schlüsselwort ermöglicht es Ihnen, auf eine wiederverwendbare Definition zu verweisen:
{
"type": "object",
"properties": {
"billing_address": { "$ref": "#/$defs/address" },
"shipping_address": { "$ref": "#/$defs/address" }
},
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^[0-9]{5}(-[0-9]{4})?$" }
},
"required": ["street", "city", "zip"]
}
}
}
Sowohl billing_address als auch shipping_address teilen sich die gleiche Struktur ohne Duplikation. Der Abschnitt $defs (in älteren Entwürfen definitions genannt) ist der konventionelle Ort, um wiederverwendbare Schemata zu speichern.
Vollständiges Beispiel: Validierung der Benutzerregistrierung
Hier ist ein reales Schema zur Validierung einer Benutzerregistrierungs-Payload. Es verwendet die meisten der Funktionen, die wir behandelt haben:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "BenutzerRegistrierung",
"description": "Schema für den POST /api/register-Endpunkt",
"type": "object",
"properties": {
"username": {
"type": "string",
"minLength": 3,
"maxLength": 30,
"pattern": "^[a-zA-Z0-9_]+$",
"description": "Alphanumerischer Benutzername, 3-30 Zeichen"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 254
},
"password": {
"type": "string",
"minLength": 8,
"maxLength": 128,
"description": "Mindestens 8 Zeichen"
},
"age": {
"type": "integer",
"minimum": 13,
"maximum": 150
},
"role": {
"type": "string",
"enum": ["benutzer", "moderator"],
"default": "benutzer"
},
"acceptedTerms": {
"type": "boolean",
"const": true
},
"tags": {
"type": "array",
"items": { "type": "string", "maxLength": 20 },
"maxItems": 5,
"uniqueItems": true
}
},
"required": ["username", "email", "password", "acceptedTerms"],
"additionalProperties": false
}
Beachten Sie, wie jedes Feld klare, durchsetzbare Einschränkungen hat. Ein Validator wird einen 2-Zeichen-Benutzernamen, ein Alter unter 13, doppelte Tags oder zusätzliche Felder, die im Schema nicht aufgeführt sind, zurückweisen.
Versuchen Sie es selbst: Fügen Sie beliebiges JSON ein und generieren Sie automatisch ein Schema mit unserem JSON Schema Generator.
JSON Schema in der realen Welt
OpenAPI / Swagger
OpenAPI verwendet JSON Schema (mit einigen Erweiterungen), um Anforderungsinhalte, Antwortformen und Abfrageparameter zu definieren. Jeder schema-Block in einer OpenAPI-Spezifikation ist ein JSON Schema. Wenn Sie OpenAPI-Dokumente schreiben, schreiben Sie bereits JSON Schema.
Formularvalidierung
Bibliotheken wie react-jsonschema-form und ajv (der schnellste JSON Schema-Validator für JavaScript) verwenden Schemata, um Formulare zur Laufzeit zu generieren und zu validieren. Definieren Sie Ihr Schema einmal, und sowohl das Backend als auch das Frontend können gegen dieselben Regeln validieren.
Datenbankschemata
MongoDB unterstützt die JSON Schema-Validierung auf der Sammlungsebene. Sie können einen $jsonSchema-Validator festlegen, der jedes Dokument zurückweist, das nicht mit Ihrem Schema übereinstimmt, beim Einfügen oder Aktualisieren.
Konfigurationsdateien
VS Code, ESLint und viele andere Tools verwenden JSON Schema, um ihre Konfigurationsdateien zu validieren. Diese Autovervollständigung, die Sie beim Bearbeiten von tsconfig.json erhalten? Sie wird von JSON Schema unterstützt.
Vergleich der Entwurfsversionen
JSON Schema hat sich durch mehrere Entwürfe weiterentwickelt. Hier sind die, auf die Sie stoßen werden:
| Entwurf | Jahr | Wichtige Ergänzungen | Status |
|---|---|---|---|
| Draft-04 | 2013 | Kernvokabular, $ref, grundlegende Typen | Legacy (immer noch weit verbreitet) |
| Draft-06 | 2017 | const, contains, propertyNames | Legacy |
| Draft-07 | 2018 | if/then/else, readOnly, writeOnly | Weitgehend unterstützt |
| 2019-09 | 2019 | $defs, unevaluatedProperties, dependentRequired | Unterstützt von großen Validatoren |
| 2020-12 | 2020 | prefixItems (ersetzt Tupelvalidierung), dynamisches $ref | Aktuell / empfohlen |
Für neue Projekte verwenden Sie 2020-12. Wenn Sie maximale Kompatibilität mit bestehenden Tools benötigen, ist Draft-07 die sichere Wahl — es hat nahezu universelle Bibliotheksunterstützung.
Häufige Fehler, die zu vermeiden sind
requiredvergessen. Eigenschaften, die unterpropertiesdefiniert sind, sind standardmäßig optional. Wenn ein Feld vorhanden sein muss, listen Sie es inrequiredauf.numberundintegerverwechseln.numberakzeptiert Dezimalzahlen;integernicht. Verwenden Sieintegerfür IDs, Zählungen und andere Ganzzahlen.- Zu früh überbeschränken. Beginnen Sie mit dem minimalen Schema, das echte Fehler abfängt. Sie können die Einschränkungen später immer weiter verschärfen — sie zu lockern ist eine breaking change.
$refnicht verwenden. Das Duplizieren desselben Sub-Schemas an mehreren Stellen ist ein Wartungsalbtraum. Extrahieren Sie gemeinsame Strukturen in$defs.format-Validierung ignorieren. Standardmäßig behandeln die meisten Validatorenformatals Annotation, nicht als Einschränkung. Sie müssen die Formatvalidierung ausdrücklich aktivieren (z. B.ajv.addFormat()oder das Übergeben von{ validateFormats: true }).
Versuchen Sie es selbst: Generieren Sie ein Schema aus einem beliebigen JSON-Beispiel mit unserem JSON Schema Generator, und passen Sie dann die Einschränkungen an Ihre Anforderungen an.