← Alle Artikel

Was ist JSON Schema? Ein praktischer Leitfaden mit Beispielen

JSON Schema ist ein Vokabular zur Beschreibung von Struktur und Einschränkungen von JSON-Daten. Lerne die Kern-Keywords, sieh reale Beispiele und validiere JSON in JavaScript, Python und im Browser.

JSON Schema ist ein Vokabular, um Struktur, Einschränkungen und Typen eines JSON-Dokuments zu beschreiben. Damit lässt sich exakt definieren, wie gültiges JSON aussehen soll — welche Schlüssel erforderlich sind, welcher Typ jeder Wert haben muss, welche Werte erlaubt sind — und dann beliebige JSON-Dokumente automatisch gegen diese Regeln validieren. Dieser Leitfaden erklärt, was JSON Schema ist, wie man eines schreibt und wie man es nutzt, um JSON in JavaScript, Python und im Browser zu validieren.

Was ist JSON Schema?

JSON Schema ist selbst ein JSON-Dokument. Es beschreibt ein anderes JSON-Dokument auf dieselbe Weise, wie ein Datenbankschema eine Tabelle beschreibt: Es deklariert die erwartete Form, die Typen und die Einschränkungen der Daten. Ein JSON Schema sagt Validatoren — Bibliotheken, APIs, Formulargeneratoren, IDEs — was „gültig" für ein bestimmtes Stück JSON bedeutet.

Die Spezifikation wird auf json-schema.org gepflegt und liegt aktuell im Draft 2020-12 vor. Sie wird von OpenAPI (dem Standard zur Dokumentation von REST-APIs), JSON Forms (UI-Generierung aus Schemas), IDE-Tooling (VS Code nutzt JSON Schema für Autocomplete in package.json und tsconfig.json) und unzähligen internen Datenpipelines verwendet.

Ein minimales JSON-Schema-Beispiel

Hier ist ein JSON-Dokument, das einen Benutzer darstellt, gefolgt von einem Schema, das seine erwartete Struktur beschreibt:

// Das zu validierende JSON-Dokument
{
  "id": 42,
  "name": "Alice",
  "email": "alice@example.com",
  "age": 30,
  "active": true
}
// Das JSON Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["id", "name", "email"],
  "properties": {
    "id":     { "type": "integer" },
    "name":   { "type": "string", "minLength": 1 },
    "email":  { "type": "string", "format": "email" },
    "age":    { "type": "integer", "minimum": 0, "maximum": 150 },
    "active": { "type": "boolean" }
  },
  "additionalProperties": false
}

Dieses Schema sagt: Das Dokument muss ein Objekt sein; id, name und email sind Pflicht; age muss, falls vorhanden, zwischen 0 und 150 liegen; und außer den fünf aufgelisteten Schlüsseln sind keine weiteren erlaubt.

Die wichtigsten Schlüsselwörter

type

Gibt den JSON-Typ eines Werts an. Gültige Typen sind "string", "number", "integer", "boolean", "array", "object" und "null". Mehrere Typen lassen sich per Array erlauben:

{ "type": ["string", "null"] }  // der Wert darf String oder null sein

properties

Definiert das Schema für jeden Schlüssel eines Objekts. Jeder Eintrag ist selbst ein Schema:

{
  "type": "object",
  "properties": {
    "firstName": { "type": "string" },
    "lastName":  { "type": "string" },
    "age":       { "type": "integer", "minimum": 0 }
  }
}

required

Ein Array von Schlüsselnamen, die im Objekt vorhanden sein müssen. Ein Schlüssel, der unter properties steht, aber nicht in required, ist optional — er darf fehlen, muss aber, wenn vorhanden, zu seinem Schema passen.

items

Definiert das Schema für jedes Element eines Arrays. Dieses Schema fordert ein Array von Strings:

{
  "type": "array",
  "items": { "type": "string" }
}

String-Einschränkungen

{
  "type": "string",
  "minLength": 1,
  "maxLength": 100,
  "pattern": "^[a-zA-Z0-9_]+
quot; // Regex-Muster }

Zahlen-Einschränkungen

{
  "type": "number",
  "minimum": 0,
  "maximum": 1,
  "multipleOf": 0.01   // muss ein Vielfaches von 0.01 sein
}

enum

Beschränkt einen Wert auf eine feste Menge erlaubter Werte:

{ "enum": ["pending", "active", "suspended", "deleted"] }

additionalProperties

Steuert, ob Schlüssel erlaubt sind, die nicht unter properties gelistet sind. Setzen Sie es auf false, um unerwartete Schlüssel abzulehnen — nützlich für strikte API-Verträge:

{ "additionalProperties": false }

Ein praxisnahes JSON-Schema-Beispiel

Hier ist ein Schema für ein Produkt in einer E-Commerce-API — wie man es in einer OpenAPI-Definition oder einem internen Datenvertrag sehen würde:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/schemas/product.json",
  "title": "Product",
  "description": "A product available for purchase",
  "type": "object",
  "required": ["id", "name", "price", "category"],
  "properties": {
    "id": {
      "type": "integer",
      "description": "Unique product identifier"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "price": {
      "type": "number",
      "minimum": 0,
      "description": "Price in USD"
    },
    "category": {
      "type": "string",
      "enum": ["electronics", "clothing", "books", "home", "sports"]
    },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "width":  { "type": "number", "minimum": 0 },
        "height": { "type": "number", "minimum": 0 },
        "depth":  { "type": "number", "minimum": 0 }
      },
      "required": ["width", "height", "depth"]
    },
    "inStock": { "type": "boolean" }
  },
  "additionalProperties": false
}

JSON gegen ein Schema validieren

Auf der Suche nach einem jsonschema-Validator? Die Standardwahl ist Ajv (JavaScript), jsonschema (Python) und Online-Dienste wie jsonschemavalidator.net. Wenn Sie den umgekehrten Weg brauchen — ein json schema aus einem Beispiel oder ein json schema aus einem json-Dokument zu erzeugen — probieren Sie in Python GenSON oder im Browser transform.tools. Das sind json schema generator-Werkzeuge, die aus einer Stichprobe ein Start-Schema ableiten. Verschärfen Sie anschließend required, additionalProperties und Wert-Einschränkungen von Hand.

In JavaScript (Ajv)

Ajv ist der am weitesten verbreitete JSON-Schema-Validator im JavaScript-Ökosystem. Er unterstützt Draft-07 und Draft 2020-12.

npm install ajv
import Ajv from 'ajv';

const ajv = new Ajv();

const schema = {
  type: 'object',
  required: ['id', 'name', 'email'],
  properties: {
    id:    { type: 'integer' },
    name:  { type: 'string', minLength: 1 },
    email: { type: 'string' },
  },
  additionalProperties: false,
};

const validate = ajv.compile(schema);

const data = { id: 42, name: 'Alice', email: 'alice@example.com' };
const valid = validate(data);

if (!valid) {
  console.error(validate.errors);
} else {
  console.log('Valid!');
}

ajv.compile(schema) gibt eine wiederverwendbare Validierungsfunktion zurück. Einmal zu kompilieren und das Ergebnis wiederholt aufzurufen ist deutlich schneller, als bei jedem Aufruf erneut zu kompilieren.

In JavaScript (Browser, ohne Abhängigkeiten)

Für einfache Typ- und Pflichtfeld-Checks ohne zusätzliche Abhängigkeit kann man manuell validieren — aber für alles, was über Trivialprüfungen hinausgeht, nehmen Sie Ajv. Die Schema-Validierungslogik ist so komplex, dass eine Eigenimplementierung fehleranfällig ist.

In Python (jsonschema)

pip install jsonschema
import json
import jsonschema
from jsonschema import validate, ValidationError

schema = {
    "type": "object",
    "required": ["id", "name", "email"],
    "properties": {
        "id":    {"type": "integer"},
        "name":  {"type": "string", "minLength": 1},
        "email": {"type": "string"},
    },
    "additionalProperties": False,
}

data = {"id": 42, "name": "Alice", "email": "alice@example.com"}

try:
    validate(instance=data, schema=schema)
    print("Valid!")
except ValidationError as e:
    print(f"Invalid: {e.message}")

Eine JSON-Datei gegen ein Schema validieren

import json
import jsonschema

with open('schema.json') as f:
    schema = json.load(f)

with open('data.json') as f:
    data = json.load(f)

jsonschema.validate(instance=data, schema=schema)

Im Browser (fixjson)

Wenn Sie ohne Codieren prüfen möchten, ob ein JSON-Dokument strukturell gültig ist, bevor Sie damit arbeiten — der JSON-Validator von fixjson prüft die Syntax und meldet Fehler sofort. Fügen Sie Ihr JSON ein, und Syntaxprobleme erscheinen inline mit exakter Zeile und Position des jeweiligen Fehlers.

Für vollständige Schema-Validierung (Prüfung von Typen, Pflichtfeldern, Einschränkungen) verwenden Sie eine der bibliotheksbasierten Ansätze oben oder ein eigenes Schema-Testwerkzeug wie jsonschemavalidator.net.

$ref: Schemas wiederverwenden

Echte Schemas definieren nicht alles inline. Das Schlüsselwort $ref erlaubt es, ein anderes Schema über seine $id oder über einen JSON-Pointer-Pfad innerhalb desselben Dokuments zu referenzieren — so bleiben Schemas DRY und kombinierbar.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$defs": {
    "address": {
      "type": "object",
      "required": ["street", "city", "country"],
      "properties": {
        "street":  { "type": "string" },
        "city":    { "type": "string" },
        "country": { "type": "string", "minLength": 2, "maxLength": 2 }
      }
    }
  },
  "type": "object",
  "properties": {
    "billingAddress":  { "$ref": "#/$defs/address" },
    "shippingAddress": { "$ref": "#/$defs/address" }
  }
}

$defs ist der Standardort für wiederverwendbare Sub-Schemas innerhalb einer einzelnen Datei (löste definitions in Draft 2019-09 ab).

Schemas kombinieren: allOf, anyOf, oneOf

JSON Schema bietet drei Kompositions-Schlüsselwörter, um „muss alle erfüllen", „muss mindestens eines erfüllen" und „muss genau eines erfüllen" auszudrücken:

// allOf: muss jedes gelistete Schema erfüllen
{
  "allOf": [
    { "type": "object" },
    { "required": ["id"] },
    { "properties": { "id": { "type": "integer" } } }
  ]
}

// anyOf: muss mindestens ein Schema erfüllen
{
  "anyOf": [
    { "type": "string" },
    { "type": "null" }
  ]
}

// oneOf: muss genau ein Schema erfüllen (sie müssen sich gegenseitig ausschließen)
{
  "oneOf": [
    { "properties": { "type": { "const": "circle" } }, "required": ["radius"] },
    { "properties": { "type": { "const": "rectangle" } }, "required": ["width", "height"] }
  ]
}

Das format-Schlüsselwort: date-time, email, uri, uuid

Über die rohen Typen hinaus annotiert das format-Schlüsselwort von JSON Schema Strings mit ihrer beabsichtigten Form — ein ISO-Date-Time, eine E-Mail-Adresse, ein URI, eine UUID, eine IP-Adresse usw. Es sieht so aus:

{
  "type": "object",
  "properties": {
    "id":         { "type": "string", "format": "uuid" },
    "created_at": { "type": "string", "format": "date-time" },
    "email":      { "type": "string", "format": "email" },
    "homepage":   { "type": "string", "format": "uri" }
  }
}

Ein feiner, aber wichtiger Punkt: In Draft 2020-12 (und 2019-09) ist das format-Schlüsselwort eine Annotation standardmäßig — es erzwingt das Format nicht, sofern der Validator nicht entsprechend konfiguriert ist. In Draft-07 und früher war es in einigen Validatoren standardmäßig eine Assertion. In Ajv strikt machen:

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);              // registriert date-time, email, uri, uuid, etc.

// In 2020-12 müssen Sie format-Assertions in Ihrem Meta-Schema aktivieren oder
// — je nach Ajv-Version — explizit { validateFormats: true } übergeben.

Gängige format-Werte: date-time, date, time, duration, email, idn-email, hostname, ipv4, ipv6, uri, uri-reference, uuid, regex, json-pointer.

Behandeln Sie format als Hinweis, nicht als Sicherheitsgrenze — ein String, der format: "email" besteht, ist weiterhin nicht vertrauenswürdige Eingabe. Für Zustellbarkeit oder echte Gültigkeit prüfen Sie außerhalb der Validierung (DNS, Bestätigungs-E-Mail, eine selbst kontrollierte Regex).

Häufige JSON-Schema-Fehler

„properties" mit „required" verwechseln

Einen Schlüssel unter properties zu listen, macht ihn nicht zur Pflicht. Ein Schlüssel in properties definiert das Schema für diesen Schlüssel, falls er auftritt. Um seine Anwesenheit zu erzwingen, muss er auch in required stehen.

„integer" verwenden, wenn „number" gemeint ist

"type": "integer" lehnt 3.14 ab. Wenn Ihr Feld eine beliebige Zahl (inkl. Dezimalstellen) sein darf, nehmen Sie "type": "number".

Vergessen, dass „additionalProperties" standardmäßig true ist

Standardmäßig erlaubt JSON Schema beliebige zusätzliche Properties, die nicht unter properties gelistet sind. Das ist Absicht — Schemas sind nach dem Postel-Prinzip standardmäßig offen. Wenn Sie ein geschlossenes Objekt wollen, setzen Sie explizit "additionalProperties": false.

$schema nicht angeben

Unterschiedliche Drafts haben unterschiedliche Semantiken. Das Weglassen des $schema-Schlüsselworts zwingt Validatoren zum Raten der Version. Immer angeben:

{ "$schema": "https://json-schema.org/draft/2020-12/schema" }

JSON-Schema-Validierung mit Sicherheitsvalidierung verwechseln

JSON Schema validiert Struktur und Typen — es ist kein Sanitization-Tool. Ein String, der "type": "string" besteht, kann immer noch SQL-Injection, XSS-Payloads oder andere bösartige Inhalte enthalten. Schema-Validierung ist ein erstes Tor, keine vollständige Sicherheitsmaßnahme.

JSON Schema und OpenAPI

OpenAPI (früher Swagger) nutzt eine Teilmenge von JSON Schema, um Request-Bodies, Response-Bodies und Parameter zu beschreiben. Wer eine OpenAPI-Spec geschrieben hat, hat JSON Schema geschrieben — wobei OpenAPI einen modifizierten Dialekt mit einigen Erweiterungen und Einschränkungen nutzt.

Das bedeutet: JSON-Schema-Wissen lässt sich direkt auf das API-Design übertragen. Der components/schemas-Abschnitt eines OpenAPI-Dokuments ist eine Sammlung von JSON Schemas, und Tools wie Stoplight, Redoc und Swagger UI rendern sie automatisch zu interaktiver Dokumentation.

Ajv in der Praxis

Zwei Flags machen sich in jedem echten Projekt bezahlt:

  • strict: true (Standard im modernen Ajv) — lehnt unbekannte Schlüsselwörter und unbekannte Formate zur Schema-Kompilierzeit ab und fängt Tippfehler wie "minimun" oder ein fehlendes $schema ab, bevor sie unbemerkt Daten durchlassen.
  • allErrors: true — sammelt jeden Validierungsfehler, statt beim ersten zu stoppen. Passt gut zu ajv.errorsText() für nutzersichtbare Meldungen.

Um Fake-JSON aus einem Schema für Tests und Fixtures zu generieren, verwenden Sie json-schema-faker: Es durchläuft das Schema und erzeugt passende Werte (Typen, Bereiche, Enums und — kombiniert mit ajv-formats — sogar format). Nützlich für property-based Testing oder als Startfüllung einer UI aus einem Schema.

Aus vorhandenem JSON ein JSON Schema erzeugen

Wenn Sie JSON-Daten haben und daraus ein Start-Schema erzeugen wollen, automatisieren mehrere Tools den Prozess:

  • quicktype.io — leitet Schemas (und Typdefinitionen für TypeScript, Go, Python u. a.) aus Beispiel-JSON ab
  • generate-schema (npm) generate-schema json schema.json data.json
  • Python: gensonpip install genson, anschließend SchemaBuilder, das ein Schema aus einem oder mehreren Beispielobjekten ableitet

Generierte Schemas sind ein Ausgangspunkt, kein fertiges Produkt. Sie leiten Typen aus Beispieldaten ab, kennen aber Ihre Geschäftsregeln nicht — sie können nicht ableiten, dass ein String-Feld eine E-Mail-Adresse ist, dass eine Ganzzahl positiv sein muss oder dass zwei Felder einander ausschließen. Prüfen und verschärfen Sie generierte Schemas immer, bevor Sie sie in Produktion nutzen.

Häufig gestellte Fragen

Wofür wird JSON Schema verwendet?

Zur Beschreibung und Validierung der Struktur von JSON-Daten — welche Schlüssel Pflicht sind, welcher Typ jeder Wert haben muss und welche Werte zulässig sind. Es treibt OpenAPI, IDE-Autocomplete für package.json/tsconfig.json, Formulargenerierung und Verträge in Datenpipelines an.

Was ist der Unterschied zwischen JSON und JSON Schema?

JSON sind die Daten; JSON Schema ist ein separates JSON-Dokument, das beschreibt, wie gültige Daten aussehen sollen. Wenn Sie mit dem Format selbst neu anfangen, starten Sie mit Was ist JSON?.

Welchen JSON-Schema-Draft soll ich verwenden?

Draft 2020-12 ist aktuell und für neue Schemas empfohlen; Draft-07 ist wegen der breiten Tool-Unterstützung weiterhin häufig. Deklarieren Sie die Version immer mit $schema, damit Validatoren nicht raten müssen.

Wie validiere ich JSON gegen ein Schema?

In JavaScript Ajv nutzen, in Python die jsonschema-Bibliothek (Beispiele oben), oder einen Web-Validator. Um zuerst zu prüfen, ob das JSON überhaupt syntaktisch gültig ist, siehe Wie man JSON validiert oder lassen Sie es durch den Validator laufen.

Validiert JSON Schema format (email, date-time, uri…)?

In Draft 2020-12 / 2019-09 ist das format-Schlüsselwort standardmäßig eine Annotation — Validatoren erzwingen es nur, wenn entsprechend konfiguriert. Mit Ajv registrieren Sie ajv-formats und aktivieren die format-Assertion, damit fehlerhafte Werte tatsächlich abgelehnt werden.

Fazit

JSON Schema verwandelt informelle Doku („dieses Feld sollte eine Zahl sein") in einen maschinenprüfbaren Vertrag, den Validatoren konsistent über Sprachen, Teams und Systeme hinweg durchsetzen können. Das Kernvokabular — type, properties, required, items, enum — deckt die große Mehrheit realer Anwendungsfälle ab. Fortgeschrittenere Mittel wie $ref, Kompositions-Schlüsselwörter und format erledigen den Rest.

Beginnen Sie mit einem minimalen Schema, das nur das erzwingt, was Sie wirklich erzwingen müssen. Fügen Sie Einschränkungen schrittweise hinzu, wenn sich Ihr Verständnis der Daten festigt. Ein Schema, das gültige Daten ablehnt, ist schlimmer als gar kein Schema.

Wenn das JSON, das Sie validieren, schon vor dem Schema-Validator Syntaxfehler hat, reparieren Sie diese zuerst — ein Schema-Validator verlangt syntaktisch korrektes JSON als Eingabe. Sobald das JSON sauber ist, validieren Sie es und wenden dann Ihr Schema an.