CodamAIDocs
Themafertig

Ersetzen mit PUT

PUT beschreibt den vollständigen Zielzustand. Hier steht, was mit fehlenden Feldern, Referenzen und Listen passiert und woher die ID kommt.

Ausprägungen
einfaches Feld fehlt → leerReferenz fehlt → gelöstabhängiges Kind fehlt → gelöschtListe fehlt → geleertKind mit id → verknüpft oder mit ersetztKind ohne id → angelegtID aus data, nicht aus dem Pfadnicht sichtbar → 404

Worum es geht

Mit PUT {basis}/update/{id} ersetzt du ein Objekt. Was du in data schickst, ist der vollständige Zielzustand: So soll das Objekt danach aussehen, Feld für Feld.

Ein PUT
Anfrage
PUT /api/rest/crm/customer/update/5a2b…
{
  "data": {
    "id": "5a2b…",
    "name": "Muster GmbH",
    "email": "neu@muster.de",
    "phone": "+49 611 123456"
  },
  "response": ["+"]
}
Antwort
{
  "data": {
    "id": "5a2b…",
    "_createdOn": "2026-03-02 09:14:00",
    "_updatedOn": "2026-09-21 10:20:31",
    "name": "Muster GmbH",
    "email": "neu@muster.de",
    "phone": "+49 611 123456",
    "note": null
  },
  "meta": { "error": false }
}

note stand vorher im Objekt, fehlt aber im PUT. Deshalb ist es jetzt leer. Die Antwort ist 200, response bestimmt wie beim Lesen, welche Felder zurückkommen, und ist Pflicht.

Vorher, Payload, Nachher

Eine Firma mit Name, Notiz, Hauptadresse (Referenz) und zwei Mitarbeitern (Liste). Die Mitarbeiter sind abhängige Kinder: Sie gehören zur Firma und werden mit ihr gelöscht.

Feldvorherim PUTnachher
companyname„CodamIC“"Codamic AG"„Codamic AG“
note„Stammkunde“fehltnull
logo„logo.png“nullnull
mainAddressAdresse Afehltgelöst, Adresse A existiert weiter
employeesAnna, Ben[{ "id": Anna, …alle Felder… }]nur Anna; Ben ist gelöscht

Die Tabelle zeigt die drei Regeln für die drei Feldarten:

Was PUT mit einem Feld macht
Einfaches FeldEinzelreferenzListe
Feld fehlt oder ist nullwird geleertwird gelöst; ein abhängiges Kind wird gelöschtalle Mitglieder werden entfernt
Feld hat einen Wertwird gesetztzeigt danach auf das genannte Objektwird genau zu dieser Liste (Zielzustand)

Ob eine Referenz nur gelöst oder das Kind gelöscht wird, legt die Beziehung im Modell fest. Siehe Beziehungstypen und Recursive-Flags.

Die Stationen eines PUT

PUT /api/rest/crm/customer/update/5a2b…
  1. CIAS
    Filterkette
    Ist das Token gültig?
    ↳ nein 401
  2. CDMS
    Feldauswahl
    Steht eine response im Körper?
    ↳ nein 400 response
  3. CDMS
    Sichtbarkeit
    Gibt es das Objekt mit data.id, und darf die Person es sehen? Gleiche Filter wie beim Lesen.
    ↳ nein 404 not-found
  4. CDMS
    Modellrolle
    Hat die Person das Recht, customer zu ändern? Ebenso für jedes Kind, das mitgeändert wird.
    ↳ nein 403 missing-permission|<rolle>
  5. CDMS
    Felder übertragen
    Jedes Feld des Modells wird auf den Wert aus data gesetzt, fehlende auf leer. Verstöße gegen Regeln werden gesammelt.
  6. Hook
    Before-Hooks
    Hooks sehen das geänderte Objekt und dürfen es noch anpassen.
  7. CDMS
    Validierung
    Sind nach den Hooks alle Regeln erfüllt?
    ↳ nein 422 validation-failed mit allen Verstößen
  8. Database
    Speichern und Zurücklesen
    Änderung schreiben, After-Hooks, dann das Objekt mit der response neu lesen
  9. 200 mit dem Objekt, wie es jetzt aussieht

Zwei Dinge fallen auf:

  1. Sichtbarkeit kommt vor der Rolle. Ein Objekt, das du nicht sehen darfst, liefert 404, auch wenn dir zusätzlich die Änderungsrolle fehlt. Siehe Warum Unsichtbares 404 liefert.
  2. Das Zurücklesen gehört zur Anfrage. Es läuft mit deinen Leserechten, in derselben Transaktion. Scheitert es, ist auch die Änderung nicht gespeichert.

_createdOn bleibt, wie es war, _updatedOn wird auf jetzt gesetzt. Alle Felder mit _ und die id überspringt CDMS beim Schreiben. Siehe Systemfelder.

Woher die ID kommt

Die id steht bei PUT zweimal im Request: im Pfad und in data. Maßgeblich ist data.id. Den Pfad wertet CDMS nicht aus.

Die id bei PUT /update/{id}
data.idid im PfadWas passiert
vorhandengleichdas Objekt mit dieser id wird ersetzt
vorhandenandersdas Objekt aus data.id wird ersetzt, ohne Fehler
fehltegal400 missing-id

Kindobjekte in einem PUT

Referenzen und Listeneinträge kannst du als Objekt schicken. Was CDMS damit macht, hängt an zwei Fragen: Hat das Kind eine id? Erlaubt die Beziehung, Kinder anzulegen oder zu ändern?

Ein Kind im PUT

Wann: Die Beziehung erlaubt kein Ändern der Kinder. Typisch für Verweise wie mainAddress.

  1. 1
    Client→CDMS
    schickt "mainAddress": { "id": "a7…" }
  2. 2
    CDMS→Database
    sucht das Objekt a7…
  3. 3
    CDMS→Client
    gibt es nicht → 404 missing-object|a7…|mainAddress
  4. 4
    CDMS
    gibt es → die Referenz zeigt jetzt darauf; weitere Felder des Kindes bleiben unberührt

Ergebnis: Die Firma zeigt auf Adresse a7…. Die Adresse selbst ändert sich nicht.

Wann: Die Beziehung erlaubt das Ändern der Kinder. Typisch für abhängige Kinder wie employees.

  1. 1
    Client→CDMS
    schickt "employees": [{ "id": "k1…", "firstname": "Anna", "lastname": "Schmidt" }]
  2. 2
    CDMS
    ersetzt das Kind k1… ebenfalls mit PUT-Regeln: fehlende Felder des Kindes werden geleert
  3. 3
    CDMS
    entfernt alle anderen Mitarbeiter, abhängige werden gelöscht

Ergebnis: Nur Anna bleibt, mit genau diesen Feldern. Schickst du nur { "id": "k1…" }, werden ihre Felder geleert, bei Pflichtfeldern kommt 422 employees[0].firstname cannot-be-null.

Wann: Du willst ein neues Kind anlegen.

  1. 1
    Client→CDMS
    schickt "employees": [{ "firstname": "Cem", "lastname": "Yıldız" }]
  2. 2
    CDMS
    Beziehung erlaubt Anlegen? → legt den Mitarbeiter an, mit Defaultwerten und CREATE-Regeln
  3. 3
    CDMS→Client
    erlaubt nicht → 400 recursive-create-not-allowed|employees

Ergebnis: Cem ist angelegt und der Firma zugeordnet. Alle bisherigen Mitarbeiter sind entfernt, weil sie in der Liste fehlen.

Die vollständigen Regeln stehen unter Die vier Fälle beim verschachtelten Schreiben und Listen als Zielzustand.

Entscheidungstabelle

Ergebnis je Feld bei PUT
Feldartim PUTBeziehung: abhängiges KindNachher
einfaches Feldfehlt / null–leer
einfaches FeldWert–neuer Wert
Einzelreferenzfehlt / nullneingelöst, das Objekt bleibt bestehen
Einzelreferenzfehlt / nulljadas Kind wird gelöscht
Listefehlt / null / []neinalle Verknüpfungen gelöst
Listefehlt / null / []jaalle Kinder gelöscht
ListeTeilliste–genau diese Mitglieder; nicht genannte werden gelöst bzw. gelöscht

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-generator – ApiProcessor (updateJson, PUT /update/{id}, /update/{id}/upload), RestPayloadProcessor (UpdatePayload, IdWrapperPayload)
  • CDMS/cdms-rest-api – AbstractRestApi.updateObject, payloads/WritePayload, Expander
  • CDMS/cdms-system-layer – AbstractSystemLayer.updateObject; AbstractLayer.recursiveUpdate, setModel, detachOrDeleteModel, reduceToTargetState, assertVisibleForWrite
  • CDMS/cdms-integrationtest – AbstractUpdateTest, AbstractRecursiveUpdate, AbstractManyToManyTest, ChangeTimestampTest
  • documentation/05-api-guide/06-schreiben.md, 20-api/04-schreibsemantik.md
Suchen