CodamAIDocs
Themafertig

Die Reihenfolge in einem Schreibvorgang

Rekursion, Before-Hooks, Validierung, Speichern, After-Hooks. Warum ein Before-Hook ein Pflichtfeld noch füllen darf.

Ausprägungen
Create, PUT, PATCHDELETEROLLBACKBefore-Hook füllt ein PflichtfeldBefore-Hook setzt einen unzulässigen WertBefore-Hook ändert ein gültiges Feld

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

PUT /api/rest/order/update/{id}
  1. 1
    Client→CDMS
    schickt das geänderte Objekt
  2. 2
    CDMS
    Sichtbarkeit prüfen, das gespeicherte Objekt laden (nur bei PUT und PATCH)
  3. 3
    CDMS
    Rekursion: für das Objekt und jedes Kind die Rolle prüfen, Werte übertragen, Regelverstöße merken, Hooks vormerken
    Eine 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.
  4. 4
    Hook
    Before-Hooks aller vorgemerkten Objekte
    Sie sehen das Objekt mit allen übertragenen Werten und dürfen es noch ändern.
  5. 5
    CDMS
    Validierung: jeden gemerkten Verstoß noch einmal gegen den Wert prüfen, der jetzt am Objekt steht
  6. 6
    CDMS
    Verstöße übrig → 422 mit allen Verstößen
  7. 7
    CDMS→Database
    übergibt das Objekt an die Datenbank, neue Objekte bekommen ihre id
  8. 8
    Hook
    After-Hooks aller vorgemerkten Objekte
  9. 9
    CDMS→Database
    flush: das SQL wird ausgeführt, die Datenbank prüft ihre Regeln, etwa eindeutige Werte
  10. 10
    CDMS→Database
    liest das Objekt mit der response der Anfrage zurück
  11. 11
    Hook
    READ-Hook für jedes zurückgelesene Objekt
  12. 12
    CDMS→Client
    Commit, dann 200 mit dem Objekt

Drei Punkte sind hier fest:

  1. Rollen vor Hooks. Alle Rollenprüfungen der Rekursion passieren, bevor ein Hook läuft. Fehlt eine Rolle, läuft kein einziger Hook. Siehe Modellrollen.
  2. 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.
  3. 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.

POST /api/rest/order/create ohne orderNr
  1. 1
    Client→CDMS
    schickt { "data": { "customer": { "id": "k-7" } } }
  2. 2
    CDMS
    Rekursion: orderNr fehlt → Verstoß cannot-be-null wird gemerkt, nicht gemeldet
  3. 3
    Hook
    Before-Hook setzt orderNr = "A-2026-0042"
  4. 4
    CDMS
    prüft orderNr noch einmal: jetzt gefüllt, der Verstoß verschwindet
  5. 5
    CDMS→Database
    speichert den Auftrag mit der Nummer aus dem Hook
    Ergebnis: 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.

Prüft CDMS, was ein Before-Hook schreibt?
Feld hatte vorher einen VerstoßWert nach dem HookWas passiert
jagültigVerstoß verschwindet, gespeichert
jaungültig422 mit der Regel, die der neue Wert bricht
neingültiggespeichert
neinungültigkeine 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

Wo die Hooks je Operation liegen

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}

  1. 1
    CDMS
    Sichtbarkeit prüfen, Objekt laden
  2. 2
    CDMS
    Rekursion: Löschrolle je Objekt prüfen, abhängige Kinder zum Entfernen vormerken, andere Beziehungen lösen, Hooks vormerken
  3. 3
    Hook
    Before-Hooks (DELETE)
  4. 4
    CDMS→Database
    übergibt das Objekt zum Entfernen
  5. 5
    Hook
    After-Hooks (DELETE)
  6. 6
    CDMS→Database
    flush, 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}

  1. 1
    CDMS
    Sichtbarkeit und Rollback-Rolle prüfen
  2. 2
    Hook
    Before-Hook (ROLLBACK) mit dem aktuellen Stand
  3. 3
    CDMS→Database
    stellt die Revision wieder her
  4. 4
    Hook
    After-Hook (ROLLBACK) mit dem wiederhergestellten Stand
  5. 5
    CDMS→Database
    flush, 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

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractSystemLayer (createObject, updateObject, patchObject, deleteObject, historyRollback: beginValidation, runAllBefore, assertValid, runAllAfter, flush)
  • CDMS/cdms-system-layer – AbstractLayer (recursivePrepare: Rollenprüfung, Datei; recursiveCreate/Update/Patch: addHooksBeforeDatabase, validateField, addHooksAfterDatabase; recursiveDelete; assertValid)
  • CDMS/cdms-system-layer – session/ValidationRequestContext (add, recheck), session/HookRequestContext (runAllBefore, runAllAfter)
  • CDMS/cdms-rest-api – RequestTransactionCommitter (Commit vor der Antwort)
  • CDMS/cdms-integrationtest – AbstractHookValidationTest (hookFillsRequiredFieldOnCreate/OnUpdate/OnPatch, hookWritingUnacceptableValueIsRefused, hookOnUnsentFieldRaisesNoViolation)
  • documentation/60-erweiterung/01-hooks.md, 02-validierung.md
Suchen