Worum es geht
Eine Anfrage schreibt oft mehr als ein Objekt: eine Firma mit neuen Mitarbeitern, eine Rechnung mit ihren Positionen, ein Löschen, das abhängige Kinder mitnimmt. Jedes dieser Objekte bekommt seine eigenen Hooks, also die Hooks seines Modells, mit seiner Operation.
CDMS führt diese Hooks nicht sofort aus. Während der Rekursion trägt es jedes Objekt in zwei Warteschlangen ein, eine für die Before-Hooks und eine für die After-Hooks. Eine Warteschlange ist eine Liste, die in der Reihenfolge des Eintragens abgearbeitet wird. Erst wenn der ganze Baum durchlaufen ist, arbeitet CDMS sie ab.
Welches Kind welche Hooks bekommt
Wann: Kind ohne id, die Beziehung hat CREATE
-
1CDMSlegt das Kind über den System-Layer seines Modells an
-
2HookBefore- und After-Hooks des Kindmodells mit
CREATE
Ergebnis: Das gilt bei Create, PUT und PATCH des Elternobjekts gleich: Das neue Kind bekommt immer CREATE.
Wann: Kind mit id, die Beziehung hat UPDATE; bei PATCH auch jeder Listeneintrag mit id
-
1CDMSüberträgt die gesendeten Werte auf das Kind
-
2HookBefore- und After-Hooks des Kindmodells mit
UPDATE(bei Create und PUT) oderPATCH(bei PATCH)
Ergebnis: Welche Kinder mitgeändert werden, steht unter Die vier Fälle beim verschachtelten Schreiben.
Wann: abhängiges Kind (Beziehung mit DELETE), beim Löschen des Elternobjekts oder weil es bei PUT oder PATCH aus der Beziehung fällt
-
1CDMSprüft die Löschrolle des Kindes und nimmt es zum Entfernen vor
-
2HookBefore- und After-Hooks des Kindmodells mit
DELETE -
3CDMSgeht die Beziehungen des Kindes genauso durch, über beliebig viele Stufen
Ergebnis: Siehe Abhängige Objekte (Kaskaden) und Löschen durch Ändern.
Wann: Beziehung ohne DELETE: das Kind fällt aus der Beziehung oder das Elternobjekt wird gelöscht
-
1CDMS→Databaseleert nur den Verweis zwischen den beiden Objekten
-
2Hookkeine Hooks für das Kind
Ergebnis: Das Kind bleibt bestehen. Für CDMS ist das keine Operation auf dem Kind.
Wann: Kind mit id, die Beziehung hat kein UPDATE (bei Create, PUT und PATCH-Einzelreferenzen)
-
1CDMSsetzt nur den Verweis auf das bestehende Kind
-
2Hookkeine Hooks für das Kind
Ergebnis: Das Kind selbst wird nicht geändert.
Die Warteschlange an einem Beispiel
Eine Abteilung hat eine Liste employees. Die Beziehung hat die Flags CREATE, UPDATE und DELETE. Vor der Anfrage gehören Anna und Ben zur Abteilung. Der Client schickt ein PUT:
PUT /api/rest/org/department/update/d-1
{
"data": {
"id": "d-1",
"name": "Vertrieb Nord",
"employees": [
{ "id": "e-anna", "name": "Anna Berg" },
{ "name": "Cem" }
]
},
"response": ["id"]
}200, { "data": { "id": "d-1" }, … }flowchart TB
D["Abteilung d-1<br/>UPDATE"] --> A["Anna<br/>UPDATE"]
D --> C["Cem, neu<br/>CREATE"]
D -.-> B["Ben, weggelassen<br/>DELETE"]
CDMS geht die Abteilung durch und trägt dabei in die Warteschlangen ein:
-
1CDMSAbteilung: Before-Eintrag
UPDATE -
2CDMSBen fehlt in der Liste und ist abhängig: Before- und After-Eintrag
DELETE, Ben wird zum Entfernen vorgemerkt -
3CDMSAnna: Before-Eintrag
UPDATE, Werte übertragen, After-EintragUPDATE -
4CDMSCem: Before-Eintrag
CREATE, Werte übertragen, After-EintragCREATE -
5CDMSAbteilung fertig: After-Eintrag
UPDATE
Dann arbeitet CDMS die Warteschlangen ab, je Operation in der festen Reihenfolge CREATE, UPDATE, PATCH, DELETE:
| Schritt | Before-Hooks | After-Hooks |
|---|---|---|
1 · CREATE | Cem | Cem |
2 · UPDATE | Abteilung, dann Anna | Anna, dann Abteilung |
3 · DELETE | Ben | Ben |
Zwischen den beiden Spalten liegen Validierung und Speichern, siehe Die Reihenfolge in einem Schreibvorgang. Innerhalb einer Operation laufen die Before-Hooks in der Reihenfolge des Eintragens, also das Elternobjekt vor seinen Kindern. Die After-Hooks trägt CDMS erst ein, wenn ein Objekt samt Kindern fertig ist. Deshalb laufen dort die Kinder vor dem Elternobjekt.
Die Reihenfolge der Operationen geht vor die Baumstruktur. Im Beispiel läuft der Before-Hook des neuen Kindes Cem vor dem Before-Hook der Abteilung, weil CREATE vor UPDATE drankommt.
Kaskade beim Löschen
Beim DELETE gibt es nur eine Operation. Hier bestimmt der Baum allein die Reihenfolge:
flowchart TB
F["Firma<br/>before 1 · after 5"] --> A1["Abteilung Nord<br/>before 2 · after 3"]
A1 --> P1["Team N-1<br/>before 3 · after 1"]
A1 --> P2["Team N-2<br/>before 4 · after 2"]
F --> A2["Abteilung Süd<br/>before 5 · after 4"]
F -.-> K["Kunde, nur abgekoppelt<br/>kein Hook"]
Die Before-Hooks laufen von oben nach unten, die After-Hooks von unten nach oben. Das Elternobjekt sieht in seinem After-Hook also, dass alle Kinder schon behandelt sind.
Wenn die Before-Hooks laufen, hat CDMS die Rekursion schon hinter sich:
- Jedes abhängige Kind ist aus den Beziehungsfeldern seines Elternobjekts genommen und zum Entfernen vorgemerkt. Der Before-Hook der Firma findet ihre Abteilungen nicht mehr in ihrer Liste. Jede Abteilung bekommt dafür ihren eigenen Hook, mit allen ihren Feldern.
- Die Rollen aller Objekte sind geprüft. Fehlt bei einem Kind die Löschrolle, läuft kein einziger Hook.
- Ein Before-Hook, der eine Exception wirft, verhindert das Löschen des ganzen Baums, egal auf welcher Stufe er sitzt.
Entscheidungstabelle
| Was mit dem Objekt passiert | Flag an der Beziehung | Hooks des Objekts |
|---|---|---|
neu, ohne id | CREATE | CREATE |
mit id, Werte gesendet | UPDATE | UPDATE bei Create und PUT, PATCH bei PATCH |
mit id, nur verknüpft | kein UPDATE | keine |
| fällt aus der Beziehung oder Elternobjekt wird gelöscht | DELETE | DELETE, auch für seine eigenen abhängigen Kinder |
| fällt aus der Beziehung oder Elternobjekt wird gelöscht | kein DELETE | keine, nur der Verweis wird geleert |
Beim Zurücklesen: READ-Hooks
Nach einem Create, PUT oder PATCH liest CDMS das Objekt mit der response der Anfrage zurück. Jede ausgebaute Referenz und jeder Eintrag einer ausgebauten Liste ist dabei ein eigenes Lesen über das eigene Modell, mit eigenem READ-Hook. Fordert die Antwort im Beispiel employees mit an, laufen die READ-Hooks der Abteilung und jedes Mitarbeiters. Siehe Referenzen und Listen ausbauen.
Fallen
Wie es weitergeht
- Wo die Warteschlangen im Ablauf abgearbeitet werden: Die Reihenfolge in einem Schreibvorgang
- Welche Kinder mitgelöscht und welche nur abgekoppelt werden: Abhängige Objekte (Kaskaden)
- Was passiert, wenn der Hook eines Kindes wirft: Wenn ein Hook scheitert