Worum es geht
Zum Ändern gibt es zwei Verben. Beide gehen an denselben Pfad {basis}/update/{id}, aber sie verstehen den Körper verschieden:
| PUT | PATCH | |
|---|---|---|
| Aussage des Körpers | „So sieht das Objekt jetzt aus.“ | „Nur das hier ändert sich.“ |
| Feld fehlt | wird geleert | bleibt unverändert |
| Feld ist null | wird geleert | wird geleert |
| Validierung | alle Felder | nur gesendete Felder |
| gut für | ein vollständiges Formular speichern | einzelne Felder ändern |
Welches Verb wofür?
flowchart TB
A["Was willst du tun?"] --> B{"Gibt es das Objekt schon?<br/>(hast du eine id?)"}
B -->|nein| CREATE["POST /create"]
B -->|ja| C{"Beschreibt dein Körper<br/>das ganze Objekt?"}
C -->|"ja, alle Felder und Listen"| PUT["PUT /update/{id}"]
C -->|"nein, nur einzelne Felder"| PATCH["PATCH /update/{id}"]
Einen Endpunkt, der selbst entscheidet, ob angelegt oder geändert wird (oft save oder „upsert“ genannt), gibt es nicht. Das entscheidet der Client, meist an der id: Hat das Objekt eine, ändert er es, sonst legt er es an.
Alle Ausprägungen
Wann: Ein Bearbeitungsformular zeigt alle Felder des Objekts, auch die Listen.
Nimm PUT mit dem ganzen Formularinhalt. Ein leeres Formularfeld soll danach auch leer sein, genau das macht PUT. Wichtig: Das Formular muss wirklich alles enthalten. Was es nicht kennt, etwa eine Liste von Anhängen, würde PUT leeren.
Ergebnis: Das Objekt entspricht genau dem Formular.
Wann: Ein Schalter „erledigt“, ein Statuswechsel, eine Inline-Bearbeitung.
-
1Client→CDMSschickt
PATCHmit{ "data": { "id": "5a2b…", "status": "DONE" }, "response": ["id", "status"] } -
2CDMSändert nur
status, prüft nurstatus
Ergebnis: Alle anderen Felder bleiben, auch wenn der Client sie gar nicht kennt.
Wann: Ein Enddatum entfernen, eine Zuordnung aufheben.
Bei PATCH schickst du das Feld ausdrücklich mit null: { "id": "5a2b…", "endDate": null }. Weglassen würde nichts ändern. Bei PUT reicht Weglassen, null geht genauso.
Ergebnis: Das Feld ist leer. Ist es ein Pflichtfeld, kommt 422 cannot-be-null.
Wann: Der Client hat eine Klasse Customer mit allen Feldern und schickt eine Instanz davon.
-
1Clienterzeugt
new Customer(), setztidundemail -
2Client→CDMSserialisiert alle Felder, die übrigen als
null:{ "id": "5a2b…", "email": "neu@…", "name": null, "phone": null, "orders": null } -
3CDMSsieht bei jedem Feld einen Schlüssel mit
null→ leertname,phoneund entfernt alleorders
Ergebnis: Das ist die null-Falle. Je nach Pflichtfeldern kommt 422 oder, schlimmer, 200 mit gelöschten Daten.
Wann: Der Client liest ein Objekt, ändert ein Feld und schickt das ganze Objekt per PATCH zurück.
Eine Leseantwort enthält auch Felder, die du nicht angefordert hast, und zwar als null. Schickst du sie per PATCH zurück, leert CDMS genau diese Felder. Dasselbe gilt für ein Formularmodell, das mit null vorbelegt ist.
Ergebnis: Felder, die du nie gesehen hast, sind danach leer.
Die null-Falle: falsch und richtig
// form is pre-filled with null for every field
const form = { id, name: null, email: null, phone: null, orders: null };
form.email = 'neu@muster.de';
await patch(form);name → geleert
email → "neu@muster.de"
phone → geleert
orders → alle Bestellungen entferntawait patch({ id, email: 'neu@muster.de' });email → "neu@muster.de"
alles andere bleibt, wie es istIn JavaScript und TypeScript fallen Felder mit undefined beim Umwandeln in JSON weg, sie sind also „nicht gesendet“. Gefährlich sind Felder, die wirklich null sind: ein mit null vorbelegtes Formular, eine zurückgelesene Antwort, ein Ausdruck wie wert || null. In Java schreibt ein üblicher JSON-Mapper jedes Feld mit, auch die leeren, als null.
Entscheidungstabelle
| Objekt existiert | Körper enthält alle Felder und Listen | Felder sollen geleert werden | Verb |
|---|---|---|---|
| nein | – | – | POST /create |
| ja | ja | – | PUT mit dem ganzen Objekt |
| ja | nein | nein | PATCH nur mit den geänderten Feldern |
| ja | nein | ja | PATCH, zu leerende Felder ausdrücklich auf null |
Fallen
Wie es weitergeht
- Die Regeln im Detail: Ersetzen mit PUT und Ändern mit PATCH
- Ein neues Objekt: Ein Objekt anlegen
- Zwei Clients ändern dasselbe: Gleichzeitige Änderungen