Worum es geht
Eine Beziehung hat in CDMS zwei Enden: company am Mitarbeiter und employees an der Firma. Beide beschreiben dieselbe Verbindung. Das Feld auf der anderen Seite heißt Gegenseite oder Rückreferenz.
flowchart LR
E["Mitarbeiter Anna"] -->|"company"| C["Firma Codamic"]
C -->|"employees"| E
CDMS pflegt beide Enden
Sobald CDMS zwei Objekte verbindet, setzt es beide Felder:
| Typ | du setzt | CDMS setzt zusätzlich |
|---|---|---|
| 1:1 | person.mainPhone = P1 | P1.person = person |
| 1:n | company.employees = [Anna] | Anna.company = company |
| n:1 | anna.company = C | nimmt Anna in C.employees auf |
| n:m | group.roles = [R1] | nimmt die Gruppe in R1.groups auf |
Genauso beim Lösen: Entfernst du Anna aus employees, wird Anna.company leer. Du kannst also jede Beziehung von der Seite aus schreiben, die für deinen Anwendungsfall bequemer ist. Beim Lesen siehst du die Verbindung auf beiden Seiten.
Von welcher Seite schreiben?
Wann: Du schreibst die Firma mit ihrer Liste employees.
-
1Client→CDMSschickt
PATCH /company/update/{id}mit"employees": [{ "id": "anna…" }, { "id": "ben…" }] -
2CDMSsetzt bei Anna und Ben
companyauf diese Firma -
3CDMSentfernt alle anderen Mitarbeiter aus der Liste, weil die Liste der Zielzustand ist
Ergebnis: Die Firma hat genau Anna und Ben. Siehe Listen als Zielzustand.
Wann: Du schreibst einen Mitarbeiter mit seiner Firma.
-
1Client→CDMSschickt
POST /employee/createmit"company": { "id": "c1…" } -
2CDMS→Databasesucht die Firma
c1… -
3CDMSsetzt
companyund nimmt den Mitarbeiter inemployeesder Firma auf
Ergebnis: Die übrigen Mitarbeiter der Firma bleiben unberührt. Für einzelne Zuordnungen ist das der einfachere Weg.
Wann: Eine Person und ihr Haupttelefon.
Beide Seiten funktionieren gleich: person.mainPhone = { "id": … } oder phone.person = { "id": … }. CDMS setzt jeweils das andere Ende. Zum Ersetzen eines Kindes löst du zuerst das alte (Feld auf null) und setzt dann das neue, am einfachsten in zwei Schritten.
Ergebnis: Genau eine Verbindung zwischen den beiden Objekten.
Wann: Gruppen und Rollen.
Du kannst group.roles schreiben oder role.groups. Beide Wege legen dieselbe Verbindung an, beide sind ein Zielzustand für die Liste, die du schickst. Die Liste der anderen Seite ändert sich nur, soweit sie diese eine Verbindung betrifft.
Ergebnis: Siehe Many-to-Many über eine Verbindungstabelle.
Die Rückreferenz mitschicken?
Beim Zurückschicken gelesener Objekte landet die Rückreferenz leicht im Request, etwa company in jedem Mitarbeiter der Liste employees:
PUT /api/rest/company/update/c1…
{
"data": {
"id": "c1…",
"companyname": "Codamic AG",
"employees": [
{ "id": "anna…", "firstname": "Anna", "lastname": "Schmidt",
"company": { "id": "c9…" } }
]
},
"response": ["+"]
}Anna gehört danach zu c1…, nicht zu c9….
Die Firma, von der aus geschrieben wird, gewinnt.
Einen Fehler gibt es nicht.| Rückreferenz im Kind | zeigt auf | Ergebnis |
|---|---|---|
| fehlt | – | CDMS setzt sie auf das Elternobjekt |
| vorhanden | das Elternobjekt | wie oben, doppelt, aber harmlos |
| vorhanden | ein anderes Objekt | wird überschrieben, das Elternobjekt gewinnt |
| vorhanden | eine unbekannte id | 404, die Anfrage scheitert |
Schicke die Rückreferenz deshalb nicht mit. Sie bringt nichts und kann nur schiefgehen.
PUT und die Liste der Gegenseite
PUT beschreibt das ganze Objekt, auch seine Listen. Das gilt für jede Seite einer Beziehung. Schreibst du eine Rolle per PUT und lässt ihre Liste groups weg, löst CDMS alle Verbindungen der Rolle zu Gruppen.
- erst die Rolle mit
groupslesen groupsmit allenids zurückschicken- sonst sind alle Verbindungen weg
- nur die geänderten Felder schicken
groupsweglassen- die Verbindungen bleiben unberührt
Fallen
Wie es weitergeht
- Was die Flags erlauben: Beziehungstypen und Recursive-Flags
- Listen im Payload: Listen als Zielzustand
- PUT und PATCH im Vergleich: PUT oder PATCH? Die null-Falle