Worum es geht
Ein Objekt löschst du mit einer einzigen Anfrage:
DELETE /api/rest/company/delete/c4…200, leerer KörperDie Anfrage hat keinen Körper, und die Antwort hat auch keinen. Es gibt kein response, weil es nach dem Löschen nichts mehr zu lesen gibt.
CDMS löscht hart: Die Zeile verschwindet aus der Datenbank. Es gibt kein Feld „gelöscht“ und keinen Papierkorb. Was danach noch übrig ist, steht unter Was nach dem Löschen bleibt.
Die Stationen
-
CDMSSichtbarkeitGibt es die Zeile, und darfst du sie sehen? Gleiche Filter wie beim Lesen: Mandant, eigene Daten, Attributfilter.↳ nein 404
not-found|<Dto>|<id> -
CDMSLöschrolleHast du die Löschrolle des Modells, hier
company-delete?↳ nein 403missing-permission|company-delete -
CDMSKaskadeAbhängige Kinder mitlöschen, alle anderen Beziehungen lösen. Jedes gelöschte Kind braucht die Löschrolle seines Modells.↳ nein 403
missing-permission|<rolle des kindes> -
HookHooksBefore-Hooks aller betroffenen Objekte. Ein Hook kann das Löschen mit einem Fehler verhindern.↳ nein Fehler des Hooks
-
DatabaseDatenbankLassen sich alle Zeilen entfernen und alle gelösten Beziehungen speichern?↳ nein 400
constraint-violation, z. B. ein gelöstes Kind darf ohne Elternobjekt nicht existieren - 200 ohne Körper, die Transaktion ist committet
Scheitert eine Station, rollt CDMS die ganze Transaktion zurück. Das Objekt, seine Kinder und alle gelösten Verbindungen bleiben, wie sie waren.
Der Ablauf im Einzelnen
sequenceDiagram
participant C as Client
participant D as CDMS
participant H as Hook
participant DB as Datenbank
C->>D: DELETE /company/delete/c4…
D->>DB: zählt die Zeile mit den Filtern des Lesens
DB-->>D: 1 (sonst 404)
D->>DB: lädt das vollständige Objekt
D->>D: Löschrolle der Firma prüfen
D->>D: Kaskade: Kinder prüfen und vormerken, Beziehungen lösen
D->>H: Before-Hooks (Firma und jedes Kind)
D->>DB: entfernen
D->>H: After-Hooks (Firma und jedes Kind)
D->>DB: flush, dann commit
D-->>C: 200, leerer Körper
Drei Dinge fallen auf:
- Sichtbarkeit kommt vor der Rolle. Ist die Zeile für dich unsichtbar, bekommst du 404, auch wenn dir die Löschrolle fehlt. So verrät CDMS nicht, ob es eine fremde
idgibt. Siehe Warum Unsichtbares 404 liefert. - Eine Leserolle brauchst du nicht. Die Sichtbarkeitsprüfung nutzt die Filter des Lesens, aber nicht die Leserolle.
order-deleteallein genügt, um eine sichtbare Bestellung zu löschen. - Nichts wird zurückgelesen. Anders als bei Create, PUT und PATCH gibt es nach dem Löschen kein Zurücklesen und keinen READ-Hook.
Hooks beim Löschen
Für jedes Objekt, das dabei gelöscht wird, laufen die Hooks mit der Methode DELETE: für das angesprochene Objekt und für jedes abhängige Kind, jeweils mit den Hooks seines Modells.
-
1CDMSgeht das Objekt und seine abhängigen Kinder durch und merkt für jedes die DELETE-Hooks vor
-
2HookBefore-Hooks laufen, das Objekt hat noch alle eigenen FelderHier kannst du prüfen, ob gelöscht werden darf, oder abhängige Daten außerhalb von CDMS aufräumen. Wirft der Hook einen Fehler, scheitert die Anfrage, und die Datenbank bleibt unverändert.
-
3CDMS→Databaseentfernt die Zeilen
-
4HookAfter-Hooks laufen
-
5CDMS→Databaseschreibt alles in die Datenbank und committet
Ein Objekt, das nur gelöst wird (Beziehung ohne DELETE-Flag), wird nicht gelöscht. Für es laufen keine DELETE-Hooks.
Varianten
Wann: DELETE {basis}/delete/{id}
-
1Client→CDMSschickt
DELETE /company/delete/c4…, ohne Körper -
2CDMSprüft Sichtbarkeit, dann die Löschrolle
-
3CDMS→Databaselöscht das Objekt, seine abhängigen Kinder und löst alle anderen Beziehungen
Ergebnis: 200 ohne Körper.
Wann: DELETE {basis}/delete, ohne id
-
1CDMS→Databasesucht das eine Objekt selbst
-
2CDMSkeins da → nichts zu tun, 200
-
3CDMSvorhanden → prüft die Löschrolle und löscht es wie ein normales Objekt, mit Kaskade und Hooks
Ergebnis: Danach ist ein neues create wieder möglich. Siehe Singletons.
Wann: DELETE {basis}/delete/{id} an der Hub-API eines abstrakten Modells
-
1Client→CDMSschickt nur die
id, kein@type -
2CDMS→Databaseliest den gespeicherten Typ zur
idnach -
3CDMSgibt es die
idnicht → 404 -
4CDMSgibt die Anfrage an die API des Untertyps weiter: Sichtbarkeit, Löschrolle, Kaskade und Hooks sind die des Untertyps
Ergebnis: Um einen Privatkunden über /crm/kunde/delete/{id} zu löschen, brauchst du die Löschrolle des Privatkunden. Siehe Abstrakte Modelle.
Entscheidungstabelle
| Zeile für dich sichtbar | Löschrolle des Modells | Löschrolle jedes abhängigen Kindes | Ergebnis |
|---|---|---|---|
| nein | – | – | 404 not-found|<Dto>|<id>, nichts gelöscht |
| ja | nein | – | 403 missing-permission|<rolle>, nichts gelöscht |
| ja | ja | fehlt bei einem Kind | 403 mit der Rolle des Kindes, nichts gelöscht |
| ja | ja | ja | 200, Objekt und abhängige Kinder gelöscht |
Bei ausgeschaltetem Strict Mode heißt der Schlüssel bei fehlender Rolle missing-delete-role, der Status bleibt 403. Löschen wird also nie still übergangen.
Zweimal löschen
Eine gelöschte Zeile gibt es nicht mehr. Ein zweites DELETE mit derselben id findet nichts und liefert 404. Für einen Client, der eine Anfrage wiederholt, weil die erste Antwort ausblieb, heißt 404 beim zweiten Versuch meistens: Das Objekt ist schon weg. Siehe Darf der Client wiederholen?
Fallen
Wie es weitergeht
- Wann Kinder mitgelöscht und wann nur gelöst werden: Abhängige Objekte (Kaskaden)
- Löschen ohne DELETE, nur durch PUT oder PATCH: Löschen durch Ändern
- Dateien: Datei-Modelle löschen