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.

JSONTech-TeamFebruary 1, 202511 min read

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:

TypGültige WerteSchema-Beispiel
string"hallo", ""{"type": "string"}
number3.14, -1, 0{"type": "number"}
integer42, -7{"type": "integer"}
booleantrue, false{"type": "boolean"}
nullnull{"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üsselwortBeschreibungBeispiel
minLengthMindestanzahl an Zeichen"minLength": 1
maxLengthHöchstanzahl an Zeichen"maxLength": 255
patternRegex, dem der String entsprechen muss"pattern": "^[A-Z]{2}\\\\d{4}$"
formatSemantischer Format-Hinweis"format": "email"
enumErlaubte Werte"enum": ["aktiv", "inaktiv"]

Zahlen-Einschränkungen

SchlüsselwortBeschreibungBeispiel
minimumWert muss >= diesem sein"minimum": 0
maximumWert muss <= diesem sein"maximum": 100
exclusiveMinimumWert muss > diesem sein"exclusiveMinimum": 0
exclusiveMaximumWert muss < diesem sein"exclusiveMaximum": 1000
multipleOfWert 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:

EntwurfJahrWichtige ErgänzungenStatus
Draft-042013Kernvokabular, $ref, grundlegende TypenLegacy (immer noch weit verbreitet)
Draft-062017const, contains, propertyNamesLegacy
Draft-072018if/then/else, readOnly, writeOnlyWeitgehend unterstützt
2019-092019$defs, unevaluatedProperties, dependentRequiredUnterstützt von großen Validatoren
2020-122020prefixItems (ersetzt Tupelvalidierung), dynamisches $refAktuell / 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

  • required vergessen. Eigenschaften, die unter properties definiert sind, sind standardmäßig optional. Wenn ein Feld vorhanden sein muss, listen Sie es in required auf.
  • number und integer verwechseln. number akzeptiert Dezimalzahlen; integer nicht. Verwenden Sie integer fü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.
  • $ref nicht 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 Validatoren format als 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.

Verwandte Tools