Skip to content
Zurück zum Blog
Tutorials

JSON-Schema-Validierung 2026: Ajv, Python und Browser im Praxisguide

Validiere JSON gegen ein Schema in Node, Python und im Browser. Draft-2020-12-Features, echte API-Muster und Copy-Paste-Beispiele für 2026. Jetzt kostenlos testen.

12 Min. Lesezeit

JSON-Schema-Validierung: JSON in Node, Python und im Browser prüfen (2026)

TL;DR: Ein JSON Schema ist ein Vertrag für JSON-Daten. Sie deklarieren Feldtypen, Pflichtfelder und Einschränkungen, und ein Validator prüft, ob ein beliebiges JSON-Dokument diesen Vertrag erfüllt. Verwenden Sie Ajv in Node für die schnellste Validierung, die Bibliothek jsonschema in Python für portable Schemas und bündeln Sie Ajv im Browser, um Formularen und Konfigurationen sofortiges Feedback zu geben. Draft 2020-12 ist die Version, die Sie 2026 für neue Projekte wählen sollten.

Was Sie hier finden: das kleinstmögliche funktionierende Beispiel, durchgängige Muster für alle drei Laufzeiten und die Praxisfallen, die zu „Validierung erfolgreich, Produktion lehnt die Daten trotzdem ab”-Bugs führen.

Was JSON Schema ist (und was nicht)

Eine Definition in einem Satz

Ein JSON Schema ist ein JSON-Dokument, das die Struktur anderer JSON-Dokumente beschreibt. Ein Validator liest das Schema und die Daten ein, bestätigt anschließend die Konformität oder gibt die fehlerhaften Pfade zurück.

Das kleinste nützliche Beispiel:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": { "name": { "type": "string" } },
  "required": ["name"]
}

{"name": "Alice"} besteht. {"age": 30} schlägt fehl (kein name). {"name": 42} schlägt fehl (name ist keine Zeichenkette). Das ist das gesamte mentale Modell.

JSON Schema vs. JSON-Syntaxprüfung

Zwei verschiedene Probleme, die häufig verwechselt werden.

DimensionJSON-SyntaxprüfungJSON-Schema-Validierung
Was wird geprüftIst das ein gültiges JSON-Dokument?Erfüllt dieses JSON den Vertrag?
ErkenntFehlende Kommas, einfache Anführungszeichen, KommentareFalsche Typen, fehlende Pflichtfelder, Werte außerhalb des Bereichs
WerkzeugeJSON.parse(), JSON-FormatiererAjv, jsonschema (Python), fastjsonschema
Wann einsetzenAls Erstes, vor dem ParsenDirekt nach dem Parsen, vor der Geschäftslogik

In der Praxis machen Sie beides: Sie formatieren die Payload im JSON-Formatierer, um zu bestätigen, dass sie überhaupt parst, und schicken sie anschließend durch ein Schema, um die Vertragstreue zu prüfen.

JSON Schema vs. JSONPath, JSON Patch, jq und TypeScript

Fünf Werkzeuge teilen sich diesen Problemraum. Die Entscheidungsmatrix:

WerkzeugWelche Frage es beantwortetWann es passt
JSON SchemaErfüllt dieses JSON die erwartete Struktur?Validierung von API-Eingaben, Konfigurationsdateien, Formular-Payloads
JSONPathWie lese ich einen Wert aus diesem JSON aus?Verschachtelte Felder extrahieren, Massenlesezugriffe
JSON Patch (RFC 6902)Wie beschreibe ich den Diff von A nach B?Kollaboratives Editieren, inkrementelle Synchronisation
jqWie verarbeite ich JSON auf der Kommandozeile?Shell-Skripte, Log-Pipelines, CI-Checks
TypeScript-TypenVerwendet mein Code diese Struktur korrekt?Compile-Zeit-Garantien innerhalb einer Codebasis

JSON Schema validiert unbekannte Daten zur Laufzeit, TypeScript prüft bekannten Code zur Übersetzungszeit. TypeScript hilft nicht bei JSON aus einem Drittanbieter-Webhook oder einer Nutzereingabe; genau dafür gibt es JSON Schema. Zod und Pydantic stehen dazwischen (Compile-Zeit-Typen plus Laufzeitvalidierung), dazu unten mehr.

JSON Schema vs. OpenAPI

Ein verbreitetes Missverständnis: OpenAPI ersetze JSON Schema. Tut es nicht. OpenAPI nutzt JSON Schema intern, um Request- und Response-Bodys zu beschreiben, und legt dann Pfade, Parameter, Sicherheitsschemata und Server-URLs darüber. Das Schema ist der Vertrag über die Datenform; OpenAPI ist der API-Vertrag, der dieses Schema umhüllt.

DimensionJSON SchemaOpenAPI
GeltungsbereichForm eines einzelnen JSON-DokumentsForm einer kompletten HTTP-API
AbhängigkeitenKeine (Schema ist eigenständiges JSON)Importiert JSON Schema für Body-Definitionen
VersionspaarungDraft 7 / Draft 2019-09 / Draft 2020-12OpenAPI 3.0 nutzt eine Draft-4-Teilmenge; OpenAPI 3.1 nutzt Draft 2020-12 nativ
Typischer EinsatzKonfigurationsdateien, Nachrichtenhüllen, Formularvalidierung, Einzel-Payload-VerträgeREST-API-Design, SDK-Generierung, Mock-Server, Vertragstests
CodegenerierungBegrenzt (einige quicktype-ähnliche Werkzeuge)Reifes Ökosystem (openapi-generator, oapi-codegen, Hersteller-SDKs)
VertragsmanagementEine Datei pro Form, kein RoutingPfade, Operationen, Auth-Flows, versionierte Endpunkte in einem Dokument

Greifen Sie zu reinem JSON Schema, wenn das Artefakt, um das es geht, ein einzelnes Dokument ist: ein Webhook-Payload, eine Konfigurationsdatei, eine Queue-Nachricht oder ein Formular. Es gibt keine HTTP-Oberfläche zu beschreiben, daher wäre OpenAPI Mehraufwand.

Greifen Sie zu OpenAPI, wenn Sie eine HTTP-API veröffentlichen und ein Dokument haben wollen, das Doku, SDK-Generierung, Mock-Server und Vertragstests speist. Definieren Sie Ihre Schemas zuerst als eigenständige JSON-Schema-Dateien in einem schemas/-Verzeichnis und referenzieren Sie sie dann per $ref aus dem OpenAPI-Dokument. So bleiben die Schemas außerhalb des API-Kontexts wiederverwendbar.

Die Versionspaarung bringt Teams ins Stolpern. OpenAPI 3.0 nutzt eine Draft-4-Teilmenge, Sie können also keine Draft-2020-12-Schlüsselwörter wie prefixItems oder unevaluatedProperties in einem 3.0-Dokument verwenden — die Generatoren ignorieren sie stillschweigend. OpenAPI 3.1 ist eine Obermenge von Draft 2020-12, alles in 2020-12 Gültige ist also auch in 3.1 gültig. Wenn Sie die Wahl haben, zielen Sie auf OpenAPI 3.1 und schreiben Sie überall Draft-2020-12-Schemas.

Ihr erstes JSON Schema (5 Minuten)

Die Schlüsselwörter, die Sie zuerst brauchen

Mit diesen kommen Sie 80 % des Wegs:

{
  "type": "object",
  "properties": {
    "id":       { "type": "integer", "minimum": 1 },
    "email":    { "type": "string", "format": "email" },
    "age":      { "type": "integer", "minimum": 0, "maximum": 150 },
    "tags":     { "type": "array", "items": { "type": "string" }, "minItems": 1 },
    "role":     { "enum": ["admin", "editor", "viewer"] },
    "metadata": { "type": "object", "additionalProperties": true }
  },
  "required": ["id", "email"],
  "additionalProperties": false
}

Das Vokabular:

  • type: string, number, integer, boolean, null, array, object
  • properties + required: Felder deklarieren und kennzeichnen, welche vorhanden sein müssen
  • enum / const: auf eine feste Menge oder einen einzelnen Literalwert beschränken
  • minimum / maximum / multipleOf: numerische Grenzen
  • minLength / maxLength / pattern: Zeichenkettenlänge und Regex
  • minItems / maxItems / uniqueItems: Array-Form
  • additionalProperties: false: nicht deklarierte Schlüssel ablehnen (für Eingabeverträge immer setzen)

JSON-Schema-Beispiele nach Anwendungsfall

Die obigen Schlüsselwörter tauchen je nach Validierungsziel in unterschiedlichen Kombinationen auf. Ein paar typische Formen:

API-Request-Body — ein Signup-Endpunkt, der E-Mail und Passwort akzeptiert:

{
  "type": "object",
  "properties": {
    "email":    { "type": "string", "format": "email" },
    "password": { "type": "string", "minLength": 8, "maxLength": 128 }
  },
  "required": ["email", "password"],
  "additionalProperties": false
}

Konfigurationsdatei — eine Logger-Konfiguration, die das Level auf eine feste Menge festnagelt:

{
  "type": "object",
  "properties": {
    "level":  { "enum": ["debug", "info", "warn", "error"] },
    "output": { "type": "string", "default": "stdout" }
  },
  "required": ["level"],
  "additionalProperties": false
}

Formular-Payload mit bedingten Regeln — wenn accountType den Wert "business" hat, wird taxId zur Pflicht:

{
  "type": "object",
  "properties": {
    "accountType": { "enum": ["personal", "business"] },
    "taxId":       { "type": "string" }
  },
  "if":   { "properties": { "accountType": { "const": "business" } } },
  "then": { "required": ["taxId"] }
}

CSV-Zeile als JSON-Datensatz — eine Zeile aus einer exportierten Bestelltabelle:

{
  "type": "object",
  "properties": {
    "orderId":   { "type": "string", "pattern": "^ORD-[0-9]{6}$" },
    "orderedOn": { "type": "string", "format": "date" },
    "totalUsd":  { "type": "number", "minimum": 0 }
  },
  "required": ["orderId", "orderedOn", "totalUsd"]
}

Webhook-Event-Hülle — oneOf unterscheidet anhand des type-Literals, jede Event-Variante hat also ihre eigene Payload-Form:

{
  "oneOf": [
    { "properties": { "type": { "const": "order.created" }, "data": { "$ref": "#/$defs/order" } } },
    { "properties": { "type": { "const": "order.refunded" }, "data": { "$ref": "#/$defs/refund" } } }
  ]
}

Diese fünf Beispiele decken den Großteil dessen ab, was Teams in der Praxis schreiben. Kopieren Sie die nächstgelegene Form und passen Sie Feldnamen an — das Schlüsselwort-Vokabular bleibt gleich.

Validieren ohne Installation

Fügen Sie Schema und Payload in den Playground unter ajv.js.org oder jsonschemavalidator.net ein und Sie erhalten sofort ein Urteil. Wenn das JSON selbst verdächtig aussieht, schicken Sie es zuerst durch den JSON-Formatierer.

Validieren in Node.js mit Ajv

Installation und ein 12-Zeilen-Beispiel

Ajv kompiliert Ihr Schema beim ersten compile-Aufruf zu einer optimierten Funktion und verwendet diese danach wieder.

npm install ajv
import Ajv from "ajv";
const ajv = new Ajv();

const schema = {
  type: "object",
  properties: {
    name: { type: "string" },
    age:  { type: "integer", minimum: 0 }
  },
  required: ["name"]
};

const validate = ajv.compile(schema);
const data = { name: "Alice", age: 30 };

if (!validate(data)) console.log(validate.errors);
else                  console.log("OK");

Auf Draft 2020-12 umschalten

Der Standardkonstruktor Ajv ist aus Gründen der Abwärtskompatibilität immer noch auf Draft 7 festgelegt. Schalten Sie 2020-12 explizit ein:

import Ajv2020 from "ajv/dist/2020";
const ajv = new Ajv2020({ strict: true, allErrors: true });

Jetzt stehen prefixItems, unevaluatedProperties und $dynamicRef zur Verfügung. Was jedes davon leistet, finden Sie weiter unten im Abschnitt zu Draft 2020-12.

format-Validierung aktivieren

Diese Falle erwischt mehr Entwickler als jede andere Eigenheit von Ajv: format: "email" tut standardmäßig nichts. Die Spezifikation behandelt format als unverbindlichen Hinweis, daher müssen Sie das Format-Modul registrieren:

npm install ajv-formats
import addFormats from "ajv-formats";
addFormats(ajv);  // jetzt validiert "format": "email" tatsächlich

Ohne diesen Schritt besteht {"email": "not-an-email"} ein Schema, das format: "email" verlangt. Installieren Sie ajv-formats in der Produktion immer.

Express-Middleware im Ernstfall

Ein Validator pro Route, beim Start kompiliert:

import express from "express";
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";

const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);

const validateUser = ajv.compile({
  type: "object",
  properties: {
    email: { type: "string", format: "email" },
    age:   { type: "integer", minimum: 13 }
  },
  required: ["email"],
  additionalProperties: false
});

const app = express();
app.use(express.json());

app.post("/users", (req, res) => {
  if (!validateUser(req.body)) {
    return res.status(400).json({ errors: validateUser.errors });
  }
  // ... Geschäftslogik
  res.status(201).json({ ok: true });
});

Der teuerste Fehler dabei: ajv.compile(schema) innerhalb des Request-Handlers aufrufen. Kompilieren Sie einmal auf Modulebene und verwenden Sie die zurückgegebene Funktion wieder. Erneutes Kompilieren pro Anfrage drückt den Durchsatz um Faktor 50 oder mehr.

Validieren in Python mit jsonschema

Installation und Grundnutzung

pip install jsonschema
from jsonschema import validate, ValidationError

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age":  {"type": "integer", "minimum": 0}
    },
    "required": ["name"]
}

try:
    validate(instance={"name": "Alice", "age": 30}, schema=schema)
    print("OK")
except ValidationError as e:
    print("FAIL:", e.message, "at", list(e.absolute_path))

Alle Fehler mit Draft202012Validator einsammeln

validate() wirft beim ersten Fehler. Um alle Probleme auf einmal aufzulisten (nützlich für Formularantworten), nutzen Sie iter_errors:

from jsonschema import Draft202012Validator

validator = Draft202012Validator(schema)
errors = sorted(validator.iter_errors(instance), key=lambda e: e.path)
for err in errors:
    print(f"  - {'/'.join(map(str, err.absolute_path))}: {err.message}")

So kann der Nutzer alles auf einmal beheben, statt mehrere Runden zu drehen.

jsonschema vs. Pydantic: Wann welche Wahl

Zwei starke Python-Bibliotheken, zwei verschiedene Aufgaben.

DimensionjsonschemaPydantic v2
SchemaformatEin JSON-Dict (das Schema ist Daten)Eine Python-Klasse mit Type Hints
PerformanceInterpretiert, ~10–100× langsamer als PydanticRust-Kern, das Schnellste im Ökosystem
Sprachübergreifende PortabilitätJa (dasselbe Schema läuft in JS, Go, Rust)Nein (nur Python)
Native FastAPI-/Modell-IntegrationManuelle KonvertierungEingebaut
Vollständige Draft-2020-12-Schlüsselwörter ($dynamicRef etc.)VollständigTeilweise

Eine brauchbare Faustregel: jsonschema für sprachübergreifende Verträge (OpenAPI, öffentliche APIs, Webhooks), Pydantic für interne Python-Dienste. Viele Teams setzen beides ein, jsonschema am Gateway zur Vertragsdurchsetzung und Pydantic auf Anwendungsebene für typisierte Geschäftslogik. Das Schema ist das portable Artefakt, identisch zu dem, was Sie an Ajv übergeben würden.

Validieren im Browser

Warum überhaupt clientseitig validieren

Drei Gründe, vom wichtigsten zum am wenigsten wichtigen:

  1. UX: Sofortiges Feedback während der Eingabe schlägt jeden Server-Round-Trip.
  2. Bandbreite: Offensichtliche Fehler verlassen den Browser gar nicht erst.
  3. Security-Hygiene: Reduziert Müllvolumen am Backend, ersetzt aber keine Server-Validierung.

Vertrauen Sie niemals nur der clientseitigen Validierung. Validieren Sie auf dem Server erneut.

Ajv für den Browser bündeln

npm install ajv ajv-formats
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";

const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);

export const validateForm = ajv.compile({
  type: "object",
  properties: {
    email:    { type: "string", format: "email" },
    password: { type: "string", minLength: 8 }
  },
  required: ["email", "password"]
});

Das Bundle wächst um etwa 30 KB gzipped: spürbar, aber nicht katastrophal. Teams setzen Ajv ein, wenn sie eine Schemadefinition zwischen Server und Client teilen wollen.

Leichtere Alternativen: Zod und Valibot

Wenn Sie das JSON-Schema-Ökosystem nicht brauchen und ohnehin in TypeScript arbeiten, liefert Ihnen ein TS-nativer Validator kleinere Bundles und engere Typinferenz:

import { z } from "zod";
const UserSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8)
});
const result = UserSchema.safeParse(data);
if (!result.success) console.log(result.error.issues);

Valibot kommt mit etwa 3 KB gzipped und einer ähnlichen API. Wählen Sie es, wenn die Bundle-Größe entscheidend ist. Der Haken: Keine der beiden Bibliotheken erzeugt JSON Schema. Wenn Sie eine einzige Quelle der Wahrheit brauchen, die Sie mit Backends, Drittanbieter-Clients oder OpenAPI-Generatoren teilen, bleiben Sie bei Ajv. Ist alles Ihr eigenes TypeScript, sind Zod und Valibot ergonomischer.

Was Draft 2020-12 hinzufügt

prefixItems für Tupel-Validierung

Draft 7 drückte Tupel über items: [] plus additionalItems aus. Draft 2020-12 trennt das sauber:

{
  "type": "array",
  "prefixItems": [
    { "type": "string" },
    { "type": "number" }
  ],
  "items": false
}

["x", 42] besteht. ["x", 42, "extra"] schlägt fehl. Das Schema liest sich genau so, wie es sich verhält.

unevaluatedProperties für zusammengesetzte Schemas

Ein subtiler Bug, der jedes Team trifft, das allOf oder oneOf einsetzt: additionalProperties: false prüft nur die unmittelbare Ebene, auf der es steht. Geschwister-Subschemas innerhalb von allOf deklarieren, was sie wollen. Die Lösung in 2020-12 heißt unevaluatedProperties: false:

{
  "allOf": [
    { "$ref": "#/$defs/base" }
  ],
  "unevaluatedProperties": false
}

Damit werden alle Properties verworfen, die von keinem Zweig ausgewertet wurden, also genau das Verhalten, das die meisten Entwickler von additionalProperties: false erwarten.

$dynamicRef für rekursive Schemas

Wer schon einmal versucht hat, ein rekursives Baum-Schema in Draft 7 zu deklarieren, kennt die nötigen Verrenkungen. $dynamicRef plus $dynamicAnchor räumt damit auf:

{
  "$dynamicAnchor": "node",
  "type": "object",
  "properties": {
    "value": { "type": "string" },
    "children": { "type": "array", "items": { "$dynamicRef": "#node" } }
  }
}

Die Rekursion ist deklarativ und lässt sich von Nachfahren überschreiben, ohne $id umschreiben zu müssen.

Draft 7 vs. 2020-12: Welche Version

  • Neues Projekt, moderne Toolchain → Draft 2020-12
  • Erstellung oder Konsum von OpenAPI 3.1 → 2020-12 ist der native Dialekt
  • Arbeit mit OpenAPI 3.0 oder älteren Diensten → Draft 4 (OpenAPI 3.0 nutzt eine Draft-4-Teilmenge; Dialekte nicht mischen)
  • Breite Validator-Kompatibilität nötig (Postman, ältere CI-Werkzeuge) → Draft 7 ist nach wie vor das sicherste Austauschformat

Jeder moderne Validator (Ajv, Python jsonschema, jsonschema-rs, Javas networknt/json-schema-validator) unterstützt 2020-12 heute.

Praxismuster

API-Eingabevalidierung

Die Express-Middleware oben ist die Produktionsform. Zwei Praktiken obendrauf: Halten Sie alle Schemas in einem Verzeichnis schemas/ im Repo-Root und ergänzen Sie einen CI-Schritt, der ajv test (oder das Python-Äquivalent) ausführt, um die Schemas selbst gegen das JSON-Schema-Meta-Schema zu validieren.

Konfigurationsdateien

Visual Studio Code bringt eine Integration mit SchemaStore mit: Autovervollständigung und Inline-Validierung für package.json, tsconfig.json und Dutzende mehr. Fügen Sie Ihren eigenen Konfigurationen ein $schema-Feld hinzu, und Editor-Nutzer bekommen dieselbe Behandlung.

CI-Test-Fixtures

Test-Fixtures veralten. Jemand aktualisiert ein Modell, eine Fixture bleibt auf der alten Form, der Test besteht trotzdem, weil die Assertions das geänderte Feld nie berührt haben. Fangen Sie das mit einer Schema-Prüfung ab, bevor die Assertions laufen:

import { glob } from "glob";
const files = await glob("__tests__/fixtures/*.json");
for (const f of files) {
  const data = JSON.parse(await fs.readFile(f, "utf8"));
  if (!validate(data)) throw new Error(`${f}: ${ajv.errorsText(validate.errors)}`);
}

Wenn die Schema-Prüfung anschlägt, ist der nächste Schritt meist ein struktureller Diff. Ziehen Sie die Fixture in JSON vergleichen gegen ein frisches Produktions-Sample, um zu sehen, was abgewichen ist. Wenn Zeitstempel und IDs den Diff dominieren, wenden Sie die Pfad-Ignore-Muster für Snapshots aus dem JSON-Diff-Guide an, um Signal von Rauschen zu trennen.

Webhook-Payloads (Stripe, GitHub)

Drittanbieter-Webhooks gehören zu den wertvollsten Einsatzorten für JSON Schema. Der Webhook ist ein Vertrag; der Anbieter kann ihn ändern; Sie wollen es im selben Moment merken, in dem das passiert. Stripe und GitHub veröffentlichen OpenAPI-Beschreibungen, aus denen sich JSON Schemas extrahieren lassen. Validieren Sie eingehende Events, dann leuchtet ein brechendes Upgrade in Ihrem Monitoring auf, anstatt still den Zustand zu beschädigen.

Schemagetriebene Formularvalidierung

React Hook Form bietet einen Adapter @hookform/resolvers/ajv; Vues VeeValidate hat ein gleichwertiges Ajv-Plugin. Beide steuern Formular-Rendering, Fehlermeldungen und Submit-Validierung aus einem einzigen JSON Schema. Das Schema ist die einzige Quelle der Wahrheit, und die UI erbt seine Regeln.

Freundliche Fehlermeldungen

Warum die Standardausgaben hart sind

Out of the box produziert Ajv Fehler wie #/properties/email format must match "email". Für einen Entwickler, der einen 400er debuggt, in Ordnung. Für einen Nutzer, der ein Checkout-Formular ausfüllt, unbrauchbar.

ajv-errors für eigene Meldungen

npm install ajv-errors
import ajvErrors from "ajv-errors";
ajvErrors(ajv);

const schema = {
  type: "object",
  properties: { email: { type: "string", format: "email" } },
  required: ["email"],
  errorMessage: {
    properties: { email: "Bitte geben Sie eine gültige E-Mail-Adresse ein" },
    required: { email: "E-Mail ist erforderlich" }
  }
};

Das Schlüsselwort errorMessage bleibt im Schema, sodass Validierungsregeln und nutzerseitige Texte gemeinsam wandern.

ajv-i18n für übersetzte Fehler

ajv-i18n liefert Übersetzungen der Standardmeldungen in über 30 Sprachen mit. Eine Zeile beim Start, und Ihr Validator spricht Spanisch, Französisch, Japanisch oder welches Locale auch immer Sie bedienen. Nützlich als Fallback, wenn Ihre errorMessage-Überschreibungen nicht jede Einschränkung abdecken.

Schema-Pfade auf Formularfelder abbilden

Jeder Ajv-Fehler hat einen instancePath wie /users/0/email. Die meisten Formular-Bibliotheken erwarten Punktpfade wie users[0].email. Einzeiler:

const fieldPath = error.instancePath.replace(/^\//, "").replace(/\//g, ".");

In Pythons jsonschema liegt das Äquivalent unter error.absolute_path. Mit . verbinden, gleiches Ergebnis.

Fünf Fallen, die die Validierung passieren und in der Produktion crashen

1. format ist standardmäßig nur ein Hinweis

Ohne ajv-formats plus addFormats(ajv) ist jedes format-Schlüsselwort wirkungslos. {"format": "email"} akzeptiert "not-an-email". Installieren Sie das Format-Paket in der Produktion immer.

2. additionalProperties steht standardmäßig auf true

Ohne additionalProperties: false akzeptiert Ihr Schema jedes nicht deklarierte Feld. Clients können zusätzliche Felder mitliefern, die die Validierung komplett umgehen. Machen Sie additionalProperties: false zum Standard für Eingabeverträge; lockern Sie es bewusst, wenn nötig.

3. additionalProperties komponiert nicht

Innerhalb von allOf, oneOf oder anyOf inspiziert additionalProperties: false nur die Properties auf seiner eigenen Ebene. Geschwister-Subschemas rutschen durch. Die Draft-2020-12-Lösung heißt unevaluatedProperties: false.

4. Remote-$ref ist ein Produktionsrisiko

$ref: "https://example.com/schema.json" lässt Ajv beim ersten compile über das Netzwerk nachladen. Das bedeutet Latenz, DoS-Exposition, falls der Remote-Host hängt, und eine MITM-Angriffsfläche. Inlinen Sie alle $ref-Ziele oder laden Sie sie zur Build-Zeit von der Festplatte.

5. Generierte Schemas driften gegenüber den echten Daten

Werkzeuge wie quicktype und typescript-json-schema erzeugen Schemas aus bestehenden Typen. Die Ausgabe lässt meist zu viel zu: jedes Feld optional, additionalProperties offen. Behandeln Sie generierte Schemas als Entwürfe, ziehen Sie sie von Hand fest und richten Sie eine CI ein, die echte Produktions-Samples gegen das Schema validiert (und umgekehrt), damit Drift schnell sichtbar wird.

Performance: Zahlen und Faustregeln

  • Ajv (Node.js): Kompilierte Validatoren erledigen eine Prüfung in deutlich unter einer Mikrosekunde. Der schnellste produktionsreife JS-Validator.
  • jsonschema (Python): Interpretiert, 10–100× langsamer als Pydantic. Tauschen Sie auf fastjsonschema, wenn das ins Gewicht fällt; es generiert Python-Code und liegt nahe an Ajv.
  • Rust und Go: jsonschema-rs und xeipuuv/gojsonschema liefern weitere 2–5× gegenüber Ajv auf der Gateway-Ebene.
  • Der mit Abstand größte Hebel ist das Vorkompilieren. ajv.compile(schema) einmal beim Modul-Laden, den zurückgegebenen Validator bei jeder Anfrage wiederverwenden. Erneutes Kompilieren pro Anfrage drückt den Durchsatz um Faktor 50 oder mehr.

Häufig gestellte Fragen

Was ist JSON-Schema-Validierung in einfachen Worten?

JSON-Schema-Validierung prüft, ob ein JSON-Dokument einem Vertrag folgt. Der Vertrag (das Schema) ist selbst JSON und deklariert Typen, Pflichtfelder und Einschränkungen. Ein Validator liest Schema und Daten ein und meldet entweder „erfolgreich” oder die Pfade, die fehlgeschlagen sind, samt Grund.

Wie validiere ich JSON online gegen ein Schema?

Fügen Sie Schema und Daten in den Playground von ajv.js.org oder bei jsonschemavalidator.net ein und Sie erhalten sofort ein Urteil. Wenn das JSON ungültig aussieht, säubern Sie es zuerst im JSON-Formatierer; beide laufen im Browser, kein Upload.

Welcher JSON-Schema-Validator ist 2026 der schnellste?

In Node erledigt Ajv mit vorkompilierten Validatoren eine Prüfung in unter einer Mikrosekunde. In Python erreicht fastjsonschema durch Code-Generierung Ajv-Klasse-Durchsatz. Auf Gateway-Ebene sind jsonschema-rs (Rust) und gojsonschema (Go) 2–5× schneller als Ajv. Was auch immer Sie wählen: einmal vorkompilieren und wiederverwenden.

Was ist der Unterschied zwischen JSON Schema und TypeScript-Typen?

TypeScript prüft den Code, den Sie schreiben, zur Übersetzungszeit. JSON Schema prüft unbekanntes JSON zur Laufzeit. TypeScript sieht JSON nicht, das aus einer HTTP-Antwort, einer Datei oder einem Nutzer-Paste kommt; genau dafür ist JSON Schema da.

Sollte ich Draft 2020-12 oder Draft 7 nehmen?

Für neue Projekte 2026 wählen Sie Draft 2020-12. prefixItems, unevaluatedProperties und $dynamicRef lösen reale Probleme. OpenAPI 3.1 nutzt 2020-12 nativ. Bleiben Sie nur bei Draft 7, wenn Sie Postman-Kompatibilität oder ältere Dienste bedienen müssen. OpenAPI 3.0 verwendet eine Draft-4-Teilmenge; mischen Sie Dialekte nicht.

Wie generiere ich ein JSON Schema aus vorhandenem JSON?

Drei Optionen: Samples in quicktype.io oder jsonschema.net einfügen; auf der Kommandozeile npx genson-js oder pip install genson && genson sample.json ausführen; oder von Hand schreiben. Automatisch generierte Schemas sind zu permissiv (jedes Feld optional, additionalProperties: true), also ziehen Sie sie immer fest, bevor Sie sie als Verträge behandeln.

Kann JSON Schema OpenAPI ersetzen?

Nein. OpenAPI nutzt JSON Schema intern, um Request- und Response-Bodies zu beschreiben, und ergänzt anschließend Pfade, Security-Schemas, Parameter und Server-URLs. Beide ergänzen sich: Schreiben Sie Ihre Schemas, referenzieren Sie sie aus einem OpenAPI-Dokument und Sie erhalten vollständige API-Verträge.

Ist JSON Schema dasselbe wie JSONPath oder jq?

Verschiedene Probleme. JSON Schema validiert die Struktur („erfüllt dieses JSON den Vertrag?”). JSONPath und jq extrahieren Werte („jeder Pod-Name in der Phase Running”). Validieren Sie mit einem Schema; abfragen Sie mit JSONPath oder jq.

Warum besteht meine Ajv-Validierung, aber die Produktion lehnt die Daten ab?

Drei Schuldige decken fast jeden Fall ab: vergessenes ajv-formats, sodass format: "email" nie validiert hat; weggelassenes additionalProperties: false, sodass zusätzliche Client-Felder durchrutschen; oder additionalProperties: false innerhalb von allOf oder oneOf und die Erkenntnis, dass es nicht komponiert. Wechseln Sie zu unevaluatedProperties: false.

Kann ich JSON-Schema-Fehlermeldungen für Endnutzer anpassen?

Ja. In Node installieren Sie ajv-errors, um errorMessage direkt im Schema einzubetten, und ajv-i18n für Übersetzungen in über 30 Locales. In Python legt jsonschema den vollständigen Validierungskontext an jedem Fehlerobjekt offen, sodass Sie Fehlertyp plus Pfad auf den Text abbilden können, den Ihr Designsystem vorsieht.

Verwandte Artikel

Alle Artikel anzeigen