Runtime
Runtime-Validierung bestätigt, ob Domain- und API-Entscheidungen sich unter realer Abfragenutzung wie erwartet verhalten. Sie ist die Ebene, auf der Dein Modell von Design zu Ausführung geht — und auf der Du Probleme erkennen kannst, bevor Deine Konsumenten es tun.
Runtime-Zweck
Die Runtime beantwortet praktische Fragen früh in Deinem Entwicklungsprozess:
- Sind Feldstrukturen vorhersagbar und konsistent?
- Sind Relationsauflösungen kohärent und korrekt verschachtelt?
- Halten Paginierungs- und Sortierungsannahmen mit den importierten Daten stand?
- Stimmen Filterausdrücke mit der korrekten Teilmenge von Datensätzen überein?
- Werden Null-Werte so behandelt, wie Deine Konsumenten es erwarten?
Indem Du diese Verhaltensweisen während der Modellierung validierst — nicht nach der Implementierung — eliminierst Du eine ganze Kategorie von Integrationsfehlern.


Runtime-Abfragepanel für Live-Verhaltenstests.
Wie die Mock-Runtime funktioniert
Die Mock-Runtime-Engine ist der Kern von Mockomat. Du akzeptiert GraphQL-Abfragen und übersetzt sie durch eine vierstufige Pipeline in MongoDB-Operationen:
1. GraphQL-Request-Parser
Der eingehende Abfragestring wird in einen abstrakten Syntaxbaum (AST) geparst. Diese Stufe validiert die Abfragesyntax und extrahiert die angeforderten Felder, Argumente und verschachtelten Auswahlen.
2. Query-Planner
Der AST wird zusammen mit Deinen Modell-Metadaten (Entitätsdefinitionen, Attribut-Flags, Relationskonfigurationen) analysiert, um einen Ausführungsplan zu erstellen. Der Planner bestimmt:
- Welche MongoDB-Sammlungen abgefragt werden
- Welche Felder projiziert werden
- Welche Filter- und Sortieroperationen angewendet werden
- Welche Relationen aufgelöst werden müssen
3. MongoDB-Query-Builder
Der Ausführungsplan wird in eine MongoDB-Aggregationspipeline übersetzt. Da MongoDB Daten in flachen (denormalisierten) Sammlungen speichert, simuliert der Query-Builder relationale Strukturen:
- Lookup-Stufen stellen verwandte Daten über Sammlungen hinweg zusammen
- Match-Stufen wenden Filterausdrücke an
- Sort-Stufen ordnen Ergebnisse nach den angeforderten Feldern
- Skip- und Limit-Stufen handhaben die Paginierung
4. Result-Assembler
Die rohen MongoDB-Ergebnisse werden umgeformt, um der erwarteten GraphQL-Antwortstruktur zu entsprechen. Verschachtelte Relationen werden in die korrekte Eltern-Kind-Hierarchie zusammengestellt, und Feldnamen werden ihren GraphQL-Entsprechungen zugeordnet.
Diese Pipeline läuft bei jeder Abfrage. Was Du in der Vorschau siehst, ist genau das, was externe Konsumenten vom selben Endpunkt erhalten.


Vierstufige Runtime-Pipeline: Parse → Plan → Build → Assemble.
Abfragebeispiele
Alle Abfragen gehen an denselben Endpunkt, mit einem API-Schlüssel des Projekts (Gastprojekte nutzen ihr Freigabe-Token — siehe Integratoren):
POST /mock/{slug}/graphql
Authorization: Bearer mck_your_api_keyDas Wurzelfeld ist der Name einer Operation aus dem API-Design. Eine Listenabfrage wählt ihre Datensätze in items aus und kann total, page und pageSize dazunehmen; eine Detailabfrage wählt die Felder direkt aus. Die Antwort enthält jedes zugeordnete Attribut der Tabelle und ihre Relationen — die Auswahl schränkt sie nicht ein.
Listenabfrage
Eine paginierte Sammlung von Datensätzen abrufen:
query {
products(page: 1, pageSize: 20) {
items {
id
name
price
category {
id
name
}
}
total
page
pageSize
}
}Detailabfrage
Einen einzelnen Datensatz anhand seines Bezeichners abrufen:
query {
product(id: "abc-123") {
id
name
price
description
category {
id
name
}
}
}Abfrage mit Filterung
Übergib die Parameter, die die Operation im API-Design definiert — hier minPrice (auf price, gte) und maxPrice (auf price, lte):
query {
products(minPrice: 10, maxPrice: 50, pageSize: 10) {
items {
id
name
price
}
total
}
}Abfrage mit Sortierung
Sortiere Ergebnisse mit sortField (ein Attributname) und sortDirection:
query {
products(sortField: "price", sortDirection: DESC, pageSize: 10) {
items {
id
name
price
}
total
}
}Abfrage mit verschachtelten Relationen
Relationen der Tabelle kommen verschachtelt zurück, eine Ebene tief:
query {
customers(pageSize: 5) {
items {
id
firstName
lastName
orders {
id
totalAmount
createdAt
}
}
total
}
}Filterung im Detail
Filter gehören zur Operation: Du definierst sie im API-Design, und die Runtime wendet sie bei jeder Anfrage an. Scope-Filter sind feste Bedingungen der Operation; Parameter sind Argumente, die der Aufrufer sendet — jeweils an ein Attribut und einen Operator gebunden, optional als Pflichtparameter oder mit Standardwert.
Verfügbare Operatoren
| Operator | Beschreibung | Funktioniert mit |
|---|---|---|
eq | Gleich | Alle Typen |
neq | Ungleich | Alle Typen |
gt / gte | Größer als / größer oder gleich | Zahlen, Datumsangaben |
lt / lte | Kleiner als / kleiner oder gleich | Zahlen, Datumsangaben |
in | Einer der Werte einer Liste | Alle Typen |
like | Enthält (ohne Groß-/Kleinschreibung) | Strings |
notIn | Keiner der Werte einer Liste (nur Scope-Filter) | Alle Typen |
isNull / isNotNull | Ist null / ist nicht null (nur Scope-Filter) | Alle Typen |
Filter kombinieren
Alle Scope-Filter und Parameter einer Operation werden mit AND verknüpft — OR und Verschachtelung gibt es zur Anfragezeit nicht. Übergib Parameterwerte inline oder als GraphQL-Variablen:
query ProductsInRange($min: Float, $max: Float) {
products(minPrice: $min, maxPrice: $max, pageSize: 20) {
items {
id
name
price
}
total
}
}Mit den Variablen { "min": 10, "max": 50 } liefert dies die Produkte mit einem Preis von 10 bis 50.
Parametervalidierung
Ein Argument, das die Operation nicht definiert, wird mit BAD_USER_INPUT abgelehnt, ebenso ein fehlender Pflichtparameter ohne Standardwert. Operationen ohne Parameter ignorieren unbekannte Argumente. Parameter definierst du in der API-Design-Ansicht.
Suche
searchTerm sucht ohne Beachtung der Groß-/Kleinschreibung in allen als durchsuchbar markierten Attributen (bis zu 64 Zeichen):
query {
products(searchTerm: "oak", pageSize: 10) {
items {
id
name
}
total
}
}Paginierung
Mockomat verwendet seitenbasierte Paginierung:
| Parameter | Beschreibung | Standard |
|---|---|---|
page | Seitennummer, beginnend bei 1 | 1 |
pageSize | Datensätze pro Seite, höchstens 100 | Standard-Seitengröße der Operation (25, sofern nicht geändert) |
Eine typische paginierte Anfrage:
query {
products(page: 3, pageSize: 20) {
items {
id
name
price
}
total
page
pageSize
}
}Dies gibt die Datensätze 41–60 zurück. total zählt alle passenden Datensätze, die letzte Seite ist also total / pageSize, aufgerundet.
Sortierung
Sortiere mit sortField (ein Attributname) und sortDirection:
| Richtung | Bedeutung |
|---|---|
ASC | Aufsteigend (A→Z, 0→9, älteste→neueste) |
DESC | Absteigend (Z→A, 9→0, neueste→älteste) |
Pro Abfrage kann nur ein Sortierfeld angewendet werden. Ohne sortField gilt die Standardsortierung der Operation; hat sie keine, kommen die Ergebnisse in Speicherreihenfolge.
Relationsdurchquerung
Eine der leistungsstärksten Funktionen der Runtime ist ihre Fähigkeit, relationale Daten aus flachen MongoDB-Sammlungen zu simulieren.
Wie es funktioniert
MongoDB speichert Daten in denormalisierten Sammlungen — jeder Datensatz ist ein flaches Dokument ohne Foreign-Key-Joins. Die Runtime simuliert relationale Strukturen durch:
- Lesen der Relationsdefinition aus Deinem Modell (Quellentität, Zielentität, Kardinalität).
- Erstellen von Lookup-Stufen in der MongoDB-Aggregationspipeline, die verwandte Sammlungen verknüpfen.
- Zusammenstellen verschachtelter Ergebnisse, die der GraphQL-Antwortstruktur entsprechen.
Das bedeutet, Deine GraphQL-Abfragen verhalten sich, als würden sie gegen eine vollständig relationale Datenbank laufen, obwohl der zugrunde liegende Speicher dokumentbasiert ist.
Was zu validieren ist
Bei der Prüfung der Relationsdurchquerung:
- 1:1-Relationen sollten ein einzelnes verschachteltes Objekt (oder null, wenn keine Übereinstimmung) zurückgeben.
- 1:n-Relationen sollten ein Array verschachtelter Objekte zurückgeben.
- Leere Relationen sollten ein leeres Array
[]zurückgeben, nicht null. - Verschachtelte Relationen werden eine Ebene tief aufgelöst: Ein verknüpfter Datensatz enthält seine eigenen Attribute, nicht seine Relationen (Customer → Order funktioniert; die Positionen der Bestellung sind nicht enthalten). Jedes Elternelement erhält höchstens 50 verknüpfte Datensätze.
Abfrageverhalten-Checkliste
Validiere für jede Schlüsselentität in Deinem Modell:
- Listenabfrage-Stabilität — gibt dieselbe Abfrage bei wiederholten Aufrufen eine konsistente Struktur zurück?
- Einzelelement-Konsistenz — gibt eine Detailabfrage alle erwarteten Felder zurück?
- Null- und fehlendes-Feld-Verhalten — werden optionale Felder korrekt als null dargestellt?
- Relationsdurchquerung — werden verschachtelte Objekte mit der korrekten Kardinalität aufgelöst?
- Filtergenauigkeit — stimmen Filterausdrücke mit der erwarteten Teilmenge überein?
- Sortierkorrektheit — erzeugt die Sortierung eine vorhersagbare, stabile Reihenfolge?
- Paginierungsgrenzen — erzeugen
pageundpageSizesaubere Seitenausschnitte ohne Duplikate?


Filter-, Sortier- und Paginierungsverhalten-Validierung.
Runtime-Inspektion und Debugging
Wenn das Verhalten falsch aussieht, inspiziere in dieser Reihenfolge:
1. Tabellen- und Attributdefinitionen prüfen
Die häufigste Ursache für unerwartetes Verhalten ist ein falsch konfiguriertes Attribut:
- Ist der Feldtyp korrekt? (Ein als
stringgespeicherter Preis wird nicht numerisch sortiert.) - Für die Suche: Ist das Feld als Durchsuchbar markiert?
- Für die Sortierung: Ist
sortFieldder Name eines Attributs, das an eine Datenspalte gebunden ist? - Hat das Feld eine konfigurierte Zuordnung?
2. Endpunkt- und Abfrage-Metadaten prüfen
Überprüfe, dass die Abfrage in der API-Design-Ansicht korrekt konfiguriert ist:
- Ist die Abfrage aktiviert?
- Sind Abfragename und Parameter korrekt?
- Ist die Paginierungskonfiguration angemessen?
3. Quellzuordnungsstatus prüfen
Wenn Felder null oder unerwartete Werte zurückgeben:
- Ist der Zuordnungstyp korrekt (Datenquelle oder Konstante)?
- Ist das Attribut bei Datenquellen-Zuordnungen an die richtige Spalte der importierten Daten gebunden, und enthält diese Spalte Werte für diese Datensätze?
- Konstante Werte erscheinen in jeder Zeile, in Zeilen importierter Daten ebenso wie in Zeilen, die aus Wertepools zusammengesetzt werden.
- Berechnete Zuordnungen: Die Runtime wertet Ausdrücke nicht aus, daher ist ein berechnetes Feld nicht Teil der Antwort.
4. Relationsrichtlinien prüfen
Wenn verschachtelte Daten fehlen oder falsch sind:
- Ist die Relationsrichtung korrekt (Quelle → Ziel)?
- Stimmt die Kardinalität (1:1 vs 1:n)?
- Existiert die Zielentität und hat zugeordnete Daten?
- Sind die Verknüpfungsspalten korrekt angegeben?
Häufige Probleme und Lösungen
| Symptom | Wahrscheinliche Ursache | Lösung |
|---|---|---|
| Leere Antwort | Die Tabelle ist nicht an importierte Daten gebunden (NOT_READY) | Die Tabelle im Zuordnungsbereich (Mappings) des Boards an importierte Daten binden |
| Felder geben null zurück | Keine Zuordnung konfiguriert | Das Attribut an eine Spalte der importierten Daten binden (Datenquellen-Zuordnung) |
| Verschachtelte Relation leer | Relation falsch konfiguriert | Richtung, Zielentität und Verknüpfungsspalten überprüfen |
| Sortierung funktioniert nicht | sortField ist kein zugeordnetes Attribut | Den Namen eines zugeordneten Attributs verwenden |
| Filter gibt alles zurück | Die Operation definiert keinen Parameter für dieses Argument | Parameter im API-Design hinzufügen |
| Falsche Datentypen | Zuordnungstyp-Abweichung | Prüfen, ob die Zuordnung den erwarteten Typ erzeugt |
| Paginierung überspringt Elemente | pageSize hat sich zwischen den Anfragen geändert | pageSize konstant halten und page um 1 erhöhen |


Runtime-Inspektionsfluss und Debug-Prüfpunkte.
Validierung vor dem Export
Die Runtime sollte die Bereitschaft bestätigen, bevor Du zur Backend-Code-Generierung übergehst. Ein Modell, das die Runtime-Validierung besteht, erzeugt mit deutlich höherer Wahrscheinlichkeit ein sauberes, funktionales generiertes Backend.
Bereitschaftskriterien
Bestätige vor dem Export, dass:
- Pflichtfelder stabil sind — alle Pflichtattribute konsistente, nicht-null Werte haben.
- Die Operations-Oberfläche beabsichtigt ist — nur die Abfragen, die Du exponieren möchtest, aktiviert sind.
- Relationsverhalten erklärbar ist — jede verschachtelte Abfrage korrekt aufgelöst wird und die Kardinalität Deinen Geschäftsregeln entspricht.
- Filter- und Sortierverhalten vorhersagbar ist — Konsumenten sich darauf verlassen können, dass diese Operationen wie dokumentiert funktionieren.
- Keine ungelösten Hinweise — die Vorschau keine Warnungen über nicht zugeordnete Attribute oder fehlende Konfiguration zeigt.
Vor-Export-Validierungs-Workflow
- Listenabfragen für jede Entität ausführen — Struktur und Datenqualität prüfen.
- Detailabfragen für Schlüsselentitäten ausführen — Feldvollständigkeit prüfen.
- Alle konfigurierten Filter testen — korrekte Teilmengenbildung verifizieren.
- Sortierung nach den Attributen testen, nach denen Deine Konsumenten sortieren — Reihenfolge verifizieren.
- Paginierungsgrenzen testen — saubere Seitenübergänge verifizieren.
- Verschachtelte Relationsabfragen testen — korrekte Zusammenstellung auf jeder Ebene verifizieren.


Vor-Export Runtime-Validierungsübersicht.