Worum es geht
Ein Schreibvorgang besteht aus vielen Schritten: Rechte prüfen, Werte übertragen, Regeln prüfen, speichern, zurücklesen. Die Hooks sitzen an zwei festen Stellen dazwischen. Wo genau, entscheidet darüber, was ein Hook tun kann und was CDMS danach noch prüft.
Die wichtigste Regel: CDMS geht zuerst den ganzen Objektbaum der Anfrage durch und merkt sich dabei für jedes Objekt seine Hooks vor. Diesen Durchlauf über das Objekt und alle seine Kinder nennt man Rekursion. Erst danach laufen die Hooks, und zwar vor dem Urteil der Validierung.
Die Schritte eines Create, PUT oder PATCH
-
1Client→CDMSschickt das geänderte Objekt
-
2CDMSSichtbarkeit prüfen, das gespeicherte Objekt laden (nur bei PUT und PATCH)
-
3CDMSRekursion: für das Objekt und jedes Kind die Rolle prüfen, Werte übertragen, Regelverstöße merken, Hooks vormerkenEine fehlende Rolle bricht hier ab, noch bevor ein einziger Hook gelaufen ist. Ein abhängiges Kind, das aus einer Liste fällt, wird schon hier zum Entfernen vorgemerkt.
-
4HookBefore-Hooks aller vorgemerkten ObjekteSie sehen das Objekt mit allen übertragenen Werten und dürfen es noch ändern.
-
5CDMSValidierung: jeden gemerkten Verstoß noch einmal gegen den Wert prüfen, der jetzt am Objekt steht
-
6CDMSVerstöße übrig → 422 mit allen Verstößen
-
7CDMS→Databaseübergibt das Objekt an die Datenbank, neue Objekte bekommen ihre
id -
8HookAfter-Hooks aller vorgemerkten Objekte
-
9CDMS→Databaseflush: das SQL wird ausgeführt, die Datenbank prüft ihre Regeln, etwa eindeutige Werte
-
10CDMS→Databaseliest das Objekt mit der
responseder Anfrage zurück -
11HookREAD-Hook für jedes zurückgelesene Objekt
-
12CDMS→ClientCommit, dann 200 mit dem Objekt
Drei Punkte sind hier fest:
- Rollen vor Hooks. Alle Rollenprüfungen der Rekursion passieren, bevor ein Hook läuft. Fehlt eine Rolle, läuft kein einziger Hook. Siehe Modellrollen.
- Hooks vor dem Urteil. Die Validierung merkt sich Verstöße nur während der Rekursion. Ob sie gelten, entscheidet sie erst nach den Before-Hooks. Siehe Validierung.
- After-Hooks vor dem flush. Wenn die After-Hooks laufen, hat die Datenbank ihre eigenen Regeln noch nicht geprüft. Ein doppelter Wert in einem eindeutigen Feld fällt erst danach auf. Siehe Ein Request, eine Transaktion.
Warum ein Before-Hook ein Pflichtfeld füllen darf
Ein Beispiel: Das Modell order hat das Pflichtfeld orderNr. Der Client kennt die Nummer nicht, ein Before-Hook vergibt sie.
-
1Client→CDMSschickt
{ "data": { "customer": { "id": "k-7" } } } -
2CDMSRekursion:
orderNrfehlt → Verstoßcannot-be-nullwird gemerkt, nicht gemeldet -
3HookBefore-Hook setzt
orderNr = "A-2026-0042" -
4CDMSprüft
orderNrnoch einmal: jetzt gefüllt, der Verstoß verschwindet -
5CDMS→Databasespeichert den Auftrag mit der Nummer aus dem HookErgebnis: 200, in der Antwort steht
orderNr
Die zweite Prüfung wendet alle Regeln des Feldes an, nicht nur die, die vorher verletzt war. Setzt der Hook statt der fehlenden Nummer einen leeren Text, meldet CDMS cannot-be-empty, weil das Feld jetzt diese Regel bricht.
Was CDMS nach den Before-Hooks noch prüft
Die zweite Prüfung betrifft nur Felder, die schon einen Verstoß hatten. Ein Feld, dessen Wert bei der Rekursion gültig war, prüft CDMS nicht noch einmal.
| Feld hatte vorher einen Verstoß | Wert nach dem Hook | Was passiert |
|---|---|---|
| ja | gültig | Verstoß verschwindet, gespeichert |
| ja | ungültig | 422 mit der Regel, die der neue Wert bricht |
| nein | gültig | gespeichert |
| nein | ungültig | keine Prüfung durch CDMS, gespeichert, sofern die Datenbank ihn beim flush annimmt |
Die Regeln der Validierung sind also vor allem ein Schutz gegen falsche Eingaben des Clients. Was dein Hook schreibt, liegt in deiner Verantwortung. Bei PATCH gilt das umso mehr: PATCH prüft nur die gesendeten Felder. Ein Feld, das der Hook setzt, der Client aber nicht geschickt hat, prüft CDMS gar nicht.
Die Varianten je Operation
Wann: POST /create, PUT /update/{id}, PATCH /update/{id}
Genau wie oben: Rekursion, Before-Hooks, Validierung, Speichern, After-Hooks, flush, Zurücklesen mit READ-Hook, Commit.
Ergebnis: Die Operation im Hook heißt CREATE, UPDATE oder PATCH, und zwar je Objekt: ein neues Kind in einem PUT bekommt CREATE.
Wann: DELETE /delete/{id}
-
1CDMSSichtbarkeit prüfen, Objekt laden
-
2CDMSRekursion: Löschrolle je Objekt prüfen, abhängige Kinder zum Entfernen vormerken, andere Beziehungen lösen, Hooks vormerken
-
3HookBefore-Hooks (
DELETE) -
4CDMS→Databaseübergibt das Objekt zum Entfernen
-
5HookAfter-Hooks (
DELETE) -
6CDMS→Databaseflush, Commit, 200 ohne Körper
Ergebnis: Keine Validierung, kein Zurücklesen, kein READ-Hook. Siehe Der Ablauf eines DELETE.
Wann: POST {basis}/{id}/rollback/{revision}
-
1CDMSSichtbarkeit und Rollback-Rolle prüfen
-
2HookBefore-Hook (
ROLLBACK) mit dem aktuellen Stand -
3CDMS→Databasestellt die Revision wieder her
-
4HookAfter-Hook (
ROLLBACK) mit dem wiederhergestellten Stand -
5CDMS→Databaseflush, Zurücklesen mit READ-Hook, Commit
Ergebnis: Keine Rekursion und keine Validierung: Die Hooks laufen nur für das angesprochene Objekt. Siehe Auf einen alten Stand zurücksetzen.
Die Reihenfolge der Hook-Aufrufe untereinander
Bei einem einzelnen Objekt ist es einfach: erst alle Before-Hooks seines Modells nach @Order, später alle After-Hooks nach @Order. Schreibt die Anfrage mehrere Objekte, etwa ein Elternobjekt mit Kindern, gibt es eine feste Reihenfolge über alle Objekte. Sie steht unter Hooks bei verschachtelten Objekten und Kaskaden.
Fallen
Wie es weitergeht
- Welche Hook-Punkte es gibt: Hooks: Arten und Zeitpunkte
- In welcher Reihenfolge Eltern und Kinder drankommen: Hooks bei verschachtelten Objekten und Kaskaden
- Die Stationen eines Create: Ein Objekt anlegen