Start / Seminare / Moderne API-Entwicklung mit REST, OpenAPI und Contract Testing

Modul

Datenmodelle mit JSON Schema beschreiben

4 Kapitel in diesem Modul-Video · Laufzeit

Vertonung mit synthetischer Stimme · Inhalte redaktionell verantwortet · © 2026 HECKER CONSULTING, alle Rechte vorbehalten

Transkript

Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.

Datenmodelle mit JSON Schema beschreiben

0:00 Im letzten Modul haben wir das Gerüst gebaut — Pfade, Operationen, Antworten. Was noch fehlt, ist der Inhalt: Wie sehen die Daten aus, die durch diese Schnittstelle fließen? Dafür verwendet OpenAPI kein eigenes Format, sondern JSON Schema. Das ist eine gute Nachricht, denn JSON Schema ist ein eigenständiger Standard mit eigener Werkzeugwelt.

0:21 Und es ist zugleich der Teil, bei dem am häufigsten Missverständnisse entstehen — vor allem bei der Frage, was ein Schema eigentlich prüft und was nicht.

Datenmodelle mit JSON Schema beschreiben

0:31 Drei Etappen liegen vor uns. Zuerst das Vokabular: Welche Schlüsselwörter gibt es, und wie beschreibt man damit Typen und Grenzen. Dann die Komposition — wie man Varianten einer Ressource beschreibt, ohne sie zu vermischen. Und zum Schluss der wichtigste Teil, weil er im Alltag am meisten Ärger spart: die Grenzen von Schemas.

0:50 Denn ein Schema kann viel, aber längst nicht alles, was Teams von ihm erwarten.

Typen und Constraints

0:55 Beginnen wir mit dem Handwerkszeug. JSON Schema in der Fassung 2020-12 hat ein überschaubares Vokabular, das nach Datentypen gegliedert ist — und genau diese Gliederung macht es leicht zu behalten. Wir gehen es nicht als Referenzliste durch, sondern schauen, welche Schlüsselwörter im Alltag wirklich tragen — und an welcher Stelle eine sehr verbreitete Annahme schlicht falsch ist.

1:17 Der Aufbau ist erfreulich systematisch: Für jeden Datentyp gibt es eine Handvoll Schlüsselwörter, und sie heißen so, wie man sie erwarten würde. Zahlen bekommen Minimum und Maximum, Zeichenketten bekommen Längen und ein Muster, Arrays bekommen Anzahlen. Wichtig ist die Fassungsangabe: 2020-12 ist die Fassung, auf die OpenAPI seit Version 3.1 aufsetzt.

1:39 Wer noch ältere Beispiele im Netz findet, stößt auf abweichende Schreibweisen — etwa bei exclusiveMaximum, das früher ein Wahrheitswert war und heute eine Zahl ist. Statt die Tabelle vorzulesen, zwei Hinweise, die im Alltag mehr bringen. Die letzte Zeile führt die Anmerkungen — title, description, default, deprecated, readOnly.

2:01 Sie prüfen nichts, sondern beschreiben. Und in dieser Zeile steckt ein sehr praktisches Werkzeug: readOnly und writeOnly. Damit trennen Sie in einem einzigen Schema, was gelesen und was geschrieben werden darf. Die Bestell-ID ist readOnly, das Passwort wäre writeOnly. Ohne dieses Paar bräuchten Sie zwei Schemas für dieselbe Ressource — und die driften garantiert.

2:25 Achten Sie auf die Mischung der Mittel. Das Muster für die Abo-Kennung ist eine echte Prüfung mit einem regulären Ausdruck. Die Kistengröße nutzt eine Aufzählung, und das ist der interessantere Fall: Eine Aufzählung ist gleichzeitig Prüfung und Dokumentation. Ein Consumer sieht sofort, welche Werte es gibt, und ein Generator baut daraus in vielen Sprachen einen eigenen Typ.

2:47 Und die Pflichtliste ganz oben ist der Teil, den man am ehesten vergisst — ohne sie ist jedes Feld optional, auch die, die es nie sein dürfen. Das ist der Punkt, an dem die meisten Teams eine falsche Annahme mitschleppen. Sie schreiben format email in Ihr Schema und gehen davon aus, dass ungültige Adressen abgelehnt werden.

3:06 Die Spezifikation sagt etwas anderes: Der Wert von format muss als Anmerkung gesammelt werden. Ob zusätzlich geprüft wird, ist optional — und muss laut Standard standardmäßig abgeschaltet sein. Wer echte Prüfung braucht, muss ausdrücklich das Format-Assertion-Vokabular erklären. In der Praxis heißt das: Verlassen Sie sich nicht auf format.

3:27 Nehmen Sie pattern und Grenzen, denn die prüfen verlässlich. Der erste Punkt ist die Wiederholung des eben Gesagten, weil er es wert ist. Der zweite ist die häufigste Ursache für Fehler, die erst in Produktion auffallen: Eine fehlende Pflichtliste macht alles optional, und Ihr Testclient schickt zufällig immer alle Felder.

3:46 Der dritte Punkt ist eine Haltungsfrage — großzügige Grenzen, damit nichts abgelehnt wird, verschieben das Problem nur nach hinten. Und der vierte ist eine hübsche Falle für Geldbeträge: Ohne multipleOf sind Bruchteile von Cent erlaubt, und irgendwann kommt einer an.

Komposition und Polymorphie

4:01 Jetzt wird es interessanter. Kaum eine reale Ressource hat nur eine Gestalt — es gibt Varianten, Untertypen, Sonderfälle. Sehen wir uns an, wie man das beschreibt, ohne dass es unlesbar wird. Standardkiste, Wunschkiste und Probierkiste sind dieselbe Ressource in drei Ausprägungen, und das Schema muss sie auseinanderhalten können. Drei Schlüsselwörter reichen dafür aus.

4:25 Drei Schlüsselwörter, die sich mit einem Bild merken lassen. allOf ist die Sammlung von Bedingungen, die alle gelten müssen — wie eine Stellenanzeige, die Ausbildung und Erfahrung und Sprachkenntnisse verlangt. anyOf genügt eine davon. Und oneOf verlangt genau eine, schließt die anderen also aus. Für echte Varianten einer Ressource ist oneOf der richtige Weg, denn eine Kiste ist entweder eine Standardkiste oder eine Wunschkiste, nie beides.

4:50 Wichtig ist das Wort genau: Wenn zwei Varianten gleichzeitig passen, ist die Prüfung fehlgeschlagen. Die Schichtung zeigt eine Rangfolge der Strenge. Ganz oben allOf, das alles verlangt — praktisch, um gemeinsame Basisfelder einzuweben. In der Mitte anyOf für Fälle, die sich überschneiden dürfen. Unten oneOf, das am strengsten ist und deshalb am meisten aussagt.

5:13 Meine Empfehlung im Alltag: Greifen Sie zu oneOf, wenn Sie Varianten meinen, und nur dann zu anyOf, wenn Überschneidung fachlich gewollt ist. Denn oneOf ist das Einzige, aus dem ein Generator saubere getrennte Typen bauen kann. Der interessante Teil ist der untere. Ohne discriminator müsste ein Consumer alle drei Varianten durchprobieren, bis eine passt — das funktioniert, ist aber langsam und in vielen Sprachen umständlich.

5:39 Mit discriminator sagen Sie: Schau in das Feld art, dort steht, welche Variante es ist. Der Generator baut daraus eine saubere Fallunterscheidung. Ein Hinweis für die Praxis: Das Unterscheidungsfeld muss in der Pflichtliste stehen, sonst kann es fehlen — und dann ist der ganze Mechanismus wirkungslos. Wiederverwendung ist richtig, aber sie hat eine Obergrenze, und die liegt bei der Lesbarkeit.

6:03 Drei Ebenen Verweise sind noch nachvollziehbar, sechs nicht mehr — und die erzeugte Dokumentationsseite zeigt dann eine Kette von Verweisen statt eines Datenmodells. Die praktikabelste Regel steht am Schluss: ein Schema pro fachlichem Begriff, nicht pro Endpunkt. Wenn die Bestellung an drei Stellen vorkommt, ist sie dreimal dasselbe Schema.

6:23 Klingt selbstverständlich, wird aber oft anders gemacht, weil jede Operation ihren eigenen Zuschnitt bekommen soll. Der erste Punkt ist der klassische oneOf-Fehler und er ist tückisch, weil er im Test nicht auffällt: Wenn zwei Varianten sich überschneiden, schlägt die Prüfung fehl — nicht weil nichts passt, sondern weil zu viel passt.

6:42 Der dritte Punkt beschreibt eine Entwicklung, die schleichend abläuft: Vererbung über allOf nachbauen, Ebene für Ebene, bis niemand mehr sagen kann, welche Felder eigentlich Pflicht sind. Wenn Sie an diesem Punkt sind, ist es meist Zeit, das Modell flach zu ziehen.

Grenzen von Schemas

6:57 Und jetzt der Teil, den ich für den wichtigsten dieses Moduls halte. Nicht was ein Schema kann, sondern was es grundsätzlich nicht kann — und was daraus für Ihre Architektur folgt. Diese Frage klingt akademisch und ist die praktischste des ganzen Moduls. Sie entscheidet nämlich, welche Prüfungen in der Anwendung landen müssen — und damit, wie Ihre Fehlerantworten aussehen.

7:19 Die Grenze verläuft an einer klaren Linie: Ein Schema sieht genau ein Dokument, sonst nichts. Es kennt nicht Ihre Datenbank, nicht den heutigen Tag, nicht die Rechte des Aufrufers und nicht die anderen Bestellungen. Alles, was diese Dinge braucht, kann es prinzipiell nicht prüfen — nicht weil das Format zu schwach wäre, sondern weil die Information fehlt.

7:39 Diese Einsicht klingt banal und erspart Ihnen trotzdem Stunden. Denn sie beantwortet die immer wiederkehrende Frage, ob man eine Regel nicht doch irgendwie ins Schema bekommt. Vergleichen Sie die beiden Spalten paarweise, dann sehen Sie das Muster. Links geht es immer nur um dieses eine Dokument: Ist das Feld da, hat es den richtigen Typ, liegt der Wert im erlaubten Bereich.

8:01 Rechts kommt jedes Mal Wissen von außen dazu — der Bestand der Datenbank, das heutige Datum, die Rechte des Kunden. Das ist der Trennstrich. Und die Fußnote sagt, was daraus folgt: Was rechts steht, gehört in die Anwendung — und seine Antwort in das Fehlerformat aus Modul 4. Beispiele sind der unterschätzteste Teil eines Schemas. Sie prüfen nichts, aber sie tragen die Dokumentation und speisen den Mock Server — dazu kommen wir in Modul 8.

8:28 Bei default ist eine Klarstellung wichtig: Es beschreibt, was der Server einsetzt, wenn das Feld fehlt. Es ist keine Prüfung und keine Anweisung an den Client. Wer im Client den Vorgabewert selbst setzt, hat ihn faktisch fixiert und merkt eine Änderung serverseitig nie. Und deprecated ist der schonende Weg, ein Feld anzukündigen, ohne es zu entfernen.

8:51 Der erste Punkt ist die Folge davon, die Grenze zu ignorieren: Fachliche Regeln werden mit verschachtelten Bedingungen ins Schema gezwungen. Technisch geht erstaunlich viel — lesbar ist davon nichts. Der dritte Punkt ist ein echtes Datenschutzthema, das regelmäßig übersehen wird: Beispiele mit echten Kundendaten aus einem Testsystem.

9:10 Sie landen in der öffentlichen Dokumentation. Und der vierte ist eine Entscheidung, die man treffen sollte statt sie geschehen zu lassen: Erlaubt Ihr Schema zusätzliche Felder oder nicht?

Übung

9:21 Setzen wir das um. Die Hofkiste hat drei Kistenarten mit unterschiedlichen Feldern — ein Fall, der genau die Werkzeuge braucht, die wir eben besprochen haben. Nehmen Sie sich besonders für den zweiten Teil der Aufgabe Zeit, die fachlichen Regeln. Dort liegt die Erkenntnis, nicht in der Syntax. Standardkiste, Wunschkiste, Probierkiste — drei Varianten, teils gemeinsame, teils eigene Felder.

9:45 Ihre Aufgabe ist, sie so zu beschreiben, dass ein Werkzeug sie unterscheiden kann: gemeinsame Felder einmal, oneOf mit discriminator für die Varianten. Der zweite Teil der Aufgabe ist der lehrreichere: Benennen Sie drei fachliche Regeln, die das Schema ausdrücklich nicht prüfen kann. Als Erweiterung setzen Sie readOnly und writeOnly ein, damit Anlegen und Lesen mit demselben Schema auskommen.

10:09 Der letzte Schritt ist der, den man gern überspringt und der am meisten findet: Beispiele gegen die Schemas validieren. Beispiele werden von Hand geschrieben, altern schnell und niemand prüft sie — bis ein Mock Server daraus Unsinn liefert. Und Schritt vier ist die eigentliche Denkarbeit dieser Übung. Drei nicht schemafähige Regeln aufzuschreiben, zwingt zu der Frage, wo diese Prüfungen stattdessen leben.

10:32 Die Antwort auf diese Frage ist eine Architekturentscheidung, keine Formatfrage. Der erste Punkt ist die Falle der Wunschkiste: Wenn sie beliebige Zusatzfelder erlaubt, passt sie auf alles — und oneOf findet plötzlich zwei zutreffende Varianten. Der zweite ist der discriminator-Fehler von vorhin, hier in freier Wildbahn.

10:51 Und der dritte ist die Konsequenz eines fehlenden fünften Schritts: Beispiele, die nicht mitvalidiert werden, passen nach der dritten Änderung nicht mehr. Sie fallen erst auf, wenn jemand den Mock benutzt — und dann zweifelt er an Ihrem Vertrag.

Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →