Worum es geht
Jedes Objekt in CDMS hat neben seinen fachlichen Feldern ein paar Systemfelder. Die setzt der Server, nicht der Client. Du erkennst sie fast immer am Unterstrich am Anfang.
Die Systemfelder
| Feld | Bedeutung | Gibt es bei | JSON-Name |
|---|---|---|---|
id | eindeutige Kennung, eine UUID | jedem Modell | id |
_createdOn | Zeitpunkt des Anlegens | jedem Modell | _createdOn |
_updatedOn | Zeitpunkt der letzten Änderung | jedem Modell | _updatedOn |
_userId | ID der Person, der das Objekt gehört | nur Benutzer-Modellen | _userId |
_MODELTYPE | konkreter Typ des Objekts | jedem Modell, wichtig bei abstrakten Modellen | @type |
_version | Versionszähler gegen gleichzeitiges Überschreiben | nur Datei-Modellen | – |
Dazu kommen interne Hilfsfelder wie _reference, die CDMS während der Verarbeitung benutzt, etwa damit verschachteltes Schreiben nicht im Kreis läuft. Werte sie im Client nicht aus.
Wer setzt was, wann?
| Anlegen (POST /create) | Ersetzen / Ändern (PUT, PATCH) | Zurücksetzen (Rollback) | |
|---|---|---|---|
| id | erzeugt die Datenbank beim Speichern; eine mitgeschickte id wird ignoriert | bleibt; sie bestimmt, welches Objekt geändert wird | bleibt |
| _createdOn | wird auf jetzt gesetzt | bleibt unverändert | bleibt |
| _updatedOn | bleibt leer | wird auf jetzt gesetzt | bleibt unverändert |
| _userId | wird auf die angemeldete Person gesetzt | bleibt unverändert | bleibt |
| _MODELTYPE / @type | ergibt sich aus dem konkreten Typ; bei abstrakten Modellen wählt der Client ihn mit @type | bleibt unverändert, ein Objekt wechselt nie seinen Typ | bleibt |
| _version | wird von der Datenbank angelegt | wird bei jeder Änderung hochgezählt | wie bei einer Änderung |
Was passiert, wenn der Client sie mitschickt?
-
1Client→CDMSschickt
{ "data": { "id": "abc", "_userId": "fremd", "_createdOn": "2020-01-01 00:00:00", "name": "Muster" }, "response": ["+"] } -
2CDMSgeht die Felder des Modells durch und überspringt
idund alle Felder, die mit_beginnen -
3CDMSsetzt
_createdOnauf jetzt und_userIdauf die angemeldete Person -
4Databasevergibt eine neue
id -
5CDMS→Clientantwortet mit den Werten des ServersErgebnis:
nameist gespeichert.id,_userIdund_createdOnstammen vom Server, nicht aus dem Request. Es gibt keinen Fehler.
Bei PUT und PATCH ist es genauso, mit einer Ausnahme: Dort muss die id in data stehen, weil sie sagt, welches Objekt gemeint ist. Geändert wird sie nie.
| Operation | id in data? | Was passiert |
|---|---|---|
| POST /create | egal | wird ignoriert, der Server vergibt eine neue |
| PUT /update/{id} | ja | bestimmt das Objekt, das ersetzt wird |
| PUT /update/{id} | nein | 400 missing-id |
| PATCH /update/{id} | ja | bestimmt das Objekt, das geändert wird |
| PATCH /update/{id} | nein | 400 missing-id |
Was du beim Lesen bekommst
Vier Angaben liest CDMS bei jedem Zugriff mit, auch wenn sie nicht in response stehen: id, _createdOn, _updatedOn und den Typ.
| Anfrage | Ergebnis |
|---|---|
["name"] | id_createdOn_updatedOn@typenameemailaddress id, _createdOn, _updatedOn und der Typ kommen immer mit. email und address stehen als null in der Antwort. |
Das hat einen praktischen Grund: Mit id und Typ kann der Client jedes Objekt eindeutig wiederfinden, auch wenn er nur ein einziges fachliches Feld angefordert hat.
Kurz zu jedem Feld
Wann: jedes Objekt
Eine UUID, in der Datenbank als 16 Byte gespeichert. Sie entsteht beim ersten Speichern und ändert sich nie. Über sie adressierst du ein Objekt in allen Pfaden: /read/{id}, /update/{id}, /delete/{id}. Singletons haben ebenfalls eine, sie steht aber in keinem Pfad.
Wann: jedes Objekt
Der Server setzt den Zeitpunkt beim Anlegen, auch für Kindobjekte, die im selben Request mit angelegt werden. Danach ändert er sich nicht mehr, auch nicht bei einem Rollback.
Wann: jedes Objekt
Der Server setzt den Zeitpunkt bei jedem PUT und PATCH auf jetzt. Beim Anlegen bleibt das Feld leer, beim Zurücksetzen auf eine alte Revision unverändert. Es sagt also, wann das Objekt zuletzt geändert wurde, aber nicht von wem und was. Dafür ist die Historie da.
Wann: nur Modelle mit dem Scope „Benutzer“
Die ID der Person, der die Zeile gehört, aus dem Claim sub des Tokens. Sie wird beim Anlegen gesetzt und danach für den Owner-Filter benutzt: Jede Person sieht nur Zeilen mit ihrer eigenen _userId. Siehe Modell-Ebenen.
Wann: jedes Objekt, entscheidend bei abstrakten Modellen
In der Datenbank heißt die Spalte _MODELTYPE, im JSON @type. Bei einem abstrakten Modell, etwa kunde mit privatkunde und firmenkunde, sagt sie, welcher konkrete Typ ein Objekt ist. Beim Anlegen unter einem abstrakten Modell muss der Client ihn nennen. Siehe Abstrakte Modelle.
Wann: nur Datei-Modelle
Ein Zähler, den die Datenbank bei jeder Änderung des Objekts erhöht. Schreiben zwei Anfragen gleichzeitig eine neue Datei in dasselbe Objekt, scheitert die zweite mit 409 statt die erste still zu überschreiben. Siehe Gleichzeitige Änderungen.
Systemfelder und Historie sind zwei Dinge
- ein Wert je Feld, der aktuelle Stand
- gibt es bei jedem Modell
- sagt: angelegt am, gehört wem, welcher Typ
- jede Änderung mit altem Stand
- mit Zeitpunkt, Person, IP-Adresse, Browser
- sagt: wer hat wann was geändert
Mehr dazu unter Audit ist nicht dasselbe wie Systemfelder.