Worum es geht
Nicht nur DELETE löscht. Auch ein PUT oder PATCH am Elternobjekt kann Kinder löschen, nämlich dann, wenn ein abhängiges Kind (Beziehung mit DELETE-Flag) danach nicht mehr dazugehört. Das passiert, wenn
- eine Liste ohne das Kind geschickt wird,
- eine Liste als leer gilt,
- eine Einzelreferenz geleert wird.
Das ist gewollt: Eine Rechnungsposition, die aus der Rechnung fällt, hat ohne Rechnung keinen Sinn. Es ist aber auch die häufigste Art, versehentlich Daten zu löschen.
Vorher und nachher
Ein Kontakt mit einem Haupttelefon mainPhone und weiteren Telefonen phones. Beide Beziehungen haben das DELETE-Flag.
| Feld | vorher | Anfrage | nachher |
|---|---|---|---|
phones | P2, P3 | "phones": [{ "id": "P2…" }] | P2; P3 gelöscht |
phones | P2, P3 | "phones": [] | leer; P2 und P3 gelöscht |
mainPhone | P1 | "mainPhone": null | leer; P1 gelöscht |
phones | P2, P3 | PUT ohne phones | leer; P2 und P3 gelöscht |
phones | P2, P3 | PATCH ohne phones | P2, P3, unverändert |
Die letzten beiden Zeilen sind der Unterschied zwischen PUT und PATCH: Bei PUT heißt „fehlt“ dasselbe wie „leer“, bei PATCH heißt „fehlt“ „nicht anfassen“.
PATCH /api/rest/crm/contact/update/c052…
{
"data": {
"id": "c052…",
"phones": [ { "id": "P2…" } ]
},
"response": ["id", { "field": "phones", "response": ["id", "number"] }]
}{ "data": { "id": "c052…",
"phones": [ { "id": "P2…", "number": "0611-17277000" } ] },
"meta": { "error": false } }P3 ist danach nicht nur aus der Liste verschwunden, sondern gelöscht. /phone/read/P3… liefert 404.
Wann gelöscht wird
| Verb | Feld in der Anfrage | Kind darin enthalten | Flag DELETE | Ergebnis für das Kind |
|---|---|---|---|---|
| – | Liste oder Referenz | ja | – | bleibt verbunden |
| – | Liste ohne das Kind, [] oder null | nein | ja | gelöscht |
| – | Liste ohne das Kind, [] oder null | nein | nein | abgekoppelt, bleibt bestehen |
| PUT | fehlt | – | ja | gelöscht (fehlt = leer) |
| PUT | fehlt | – | nein | abgekoppelt (fehlt = leer) |
| PATCH | fehlt | – | – | unverändert |
| – | Einzelreferenz null | – | ja | gelöscht |
„Enthalten“ heißt: Das Kind steht mit seiner id in der Liste bzw. der Referenz. Welche Felder du sonst mitschickst, spielt dafür keine Rolle. Siehe Listen als Zielzustand.
Was dabei passiert
-
1Client→CDMSschickt
PATCH /contact/update/c052…mitphones: [P2] -
2CDMSprüft Sichtbarkeit und Änderungsrolle des Kontakts
-
3CDMSvergleicht die Liste mit dem gespeicherten Stand: P3 fehlt
-
4CDMS
phoneshat DELETE → P3 wird gelöschtOhne DELETE-Flag würde P3 nur abgekoppelt: Sein Verweis auf den Kontakt wird leer, P3 bleibt. -
5CDMSprüft die Löschrolle des Telefon-Modells (oder eine Feldrolle an
phones) -
6CDMS→ClientRolle fehlt → 403, nichts wird gespeichert, auch die übrigen Änderungen nicht
-
7HookDELETE-Hooks von P3 laufen, zusammen mit den UPDATE- bzw. PATCH-Hooks des Kontakts
-
8CDMS→Databaselöscht P3 samt seinen eigenen abhängigen Kindern und Dateien, speichert den Kontakt, liest zurück
Für das gelöschte Kind gilt alles aus Abhängige Objekte (Kaskaden): Es braucht die Löschrolle seines Modells, seine eigenen abhängigen Kinder gehen mit, seine übrigen Beziehungen werden gelöst.
Fallen
Wie es weitergeht
- Die Regeln für Listen: Listen als Zielzustand
- PUT und PATCH im Vergleich: PUT oder PATCH? Die null-Falle
- Was mitgelöscht wird: Abhängige Objekte (Kaskaden)