Worum es geht
Bei jedem Lesen sagst du CDMS in der Liste response, welche Felder du zurückhaben willst. Du kannst jedes Feld einzeln nennen. Bei Modellen mit vielen Feldern ist das mühsam, deshalb gibt es zwei Abkürzungen, die Wildcards:
| Zeichen | Merkhilfe | liefert |
|---|---|---|
+ | „plus die einfachen Felder“ | alle einfachen Felder: Text, Zahl, Datum, Ja/Nein |
* | „Stern ist mehr“ | alle einfachen Felder und alle Referenzen (auch Listen), Referenzen aber nur mit ihrer id |
Das Beispielmodell
Alle Bilder auf dieser Seite benutzen dasselbe Modell employee (Mitarbeiter):
| Feld | Art | Beispielwert |
|---|---|---|
id | einfach | "7f3…" |
firstname | einfach | "Daniel" |
lastname | einfach | "Mertins" |
company | Referenz auf company | { "id": "a1…" } |
department | Referenz auf department | { "id": "d4…" } |
Die zwei Grundformen
| Anfrage | Ergebnis |
|---|---|
["+"] | idfirstnamelastnamecompanydepartment Nur die einfachen Felder. Die Referenzen fehlen. |
["*"] | idfirstnamelastnamecompany (nur id)department (nur id) Einfache Felder und beide Referenzen, die Referenzen nur mit ihrer id. |
* als Request und ResponsePOST /api/rest/hr/employee/read/7f3…
{ "response": ["*"] }{
"data": {
"id": "7f3…",
"firstname": "Daniel",
"lastname": "Mertins",
"company": { "id": "a1…", "companyname": null },
"department": { "id": "d4…", "name": null }
},
"meta": { "error": false }
}Wenn du mehr als die id einer Referenz brauchst, baust du sie ausdrücklich aus. Das steht unter Referenzen ausbauen.
Die Teil-Wildcards
Beide Zeichen kannst du mit einem Wortanfang oder einem Wortende kombinieren. Das Zeichen steht entweder ganz vorn oder ganz hinten:
| Form | liest sich als | trifft |
|---|---|---|
name+ | „einfache Felder, die mit name beginnen“ | Präfix |
+name | „einfache Felder, die auf name enden“ | Suffix |
name* | wie name+, plus Referenzen, die mit name beginnen | Präfix |
*name | wie +name, plus Referenzen, die auf name enden | Suffix |
| Anfrage | Ergebnis |
|---|---|
["+name"] | idfirstnamelastnamecompanydepartment Beide enden auf name. |
["first+"] | idfirstnamelastnamecompanydepartment Nur firstname beginnt mit first. |
["*ment"] | idfirstnamelastnamecompanydepartment (nur id) department ist eine Referenz und endet auf ment. Mit * ist sie dabei, aber nur mit id. |
["depart*"] | idfirstnamelastnamecompanydepartment (nur id) Dasselbe Ergebnis über den Wortanfang. |
["+pany"] | idfirstnamelastnamecompanydepartment company passt zwar auf pany, ist aber eine Referenz, und + nimmt nie Referenzen auf. Ergebnis: kein Feld, trotzdem 200. |
["first+name"] | idfirstnamelastnamecompanydepartment Das Zeichen steht in der Wortmitte. Das ist keine Wildcard und passt auf nichts, auch nicht auf firstname. Kein Fehler, einfach leer. |
Wie CDMS eine Wildcard auflöst
Die Auflösung übernimmt eine Komponente im REST-Layer, der Expander. Für jeden Eintrag der response-Liste geht er so vor:
flowchart TB
E["Eintrag aus response"] --> Q1{"Ist es ein Objekt<br/>{ field, response }?"}
Q1 -->|ja| R["Referenz gezielt ausbauen<br/>(eigene Seite)"]
Q1 -->|nein| Q2{"Enthält der Text<br/>+ oder * am Anfang<br/>oder am Ende?"}
Q2 -->|nein| F["genau dieses Feld übernehmen"]
Q2 -->|"ja, +"| P["alle einfachen Felder,<br/>deren Name passt"]
Q2 -->|"ja, *"| S["alle einfachen Felder, deren Name passt<br/>+ alle Referenzen, deren Name passt<br/>(nur mit id)"]
P --> X["exclude abziehen"]
S --> X
F --> Z["Ergebnis: Liste der Felder<br/>→ genau diese Spalten werden aus der DB gelesen"]
X --> Z
Vier Regeln, die du dir merken solltest:
- Wortanfang oder Wortende, sonst nichts. Es gibt keine regulären Ausdrücke, kein Zeichen in der Wortmitte und nie zwei Zeichen in einem Eintrag.
- Groß- und Kleinschreibung zählen.
+Nametrifftfirstnamenicht. - Mehrere Einträge werden zusammengezählt.
["+name", "*ment"]liefertfirstname,lastnameunddepartment. - Kein Treffer ist kein Fehler. Eine Wildcard, die nichts trifft, liefert einfach keine Felder, die Antwort ist trotzdem 200.
Felder wieder herausnehmen: exclude
Mit exclude nimmst du einzelne Felder aus dem Ergebnis einer Wildcard wieder heraus:
{ "response": ["*"], "exclude": ["department"] }{ "data": { "id": "7f3…", "firstname": "Daniel",
"lastname": "Mertins", "company": { "id": "a1…" },
"department": null } }- auf Felder, die durch eine Wildcard dazugekommen sind
["*"]+exclude: ["department"]→departmentfehlt
- auf Felder, die du namentlich angefordert hast
["department", "+"]+exclude: ["department"]→departmentist trotzdem da
Alle Ausprägungen auf einen Blick
Wann: Du brauchst alle einfachen Felder und keine Referenzen.
-
1Client→CDMSschickt
{ "response": ["+"] } -
2CDMSnimmt alle einfachen Felder des Modells auf
-
3CDMS→Datenbankliest genau diese Spalten, ohne Join
Ergebnis: Alle einfachen Felder. Referenzen stehen als null in der Antwort.
Wann: Du willst einen schnellen Überblick über alles, auch über die Referenzen.
-
1Client→CDMSschickt
{ "response": ["*"] } -
2CDMSnimmt alle einfachen Felder und alle Referenzen auf
-
3CDMSprüft für jede Referenz die Leserolle des referenzierten Modells
-
4CDMS→Datenbankliest die Spalten und holt jede Referenz per LEFT JOIN, aber nur ihre
id
Ergebnis: Alle einfachen Felder, dazu jede Referenz als { "id": … }.
Wann: Du willst eine Gruppe ähnlich benannter Felder, z. B. alle …Datum-Felder.
Wie + bzw. *, nur dass vorher nach dem Namen gefiltert wird. Das Zeichen steht vorn (Suffix-Suche) oder hinten (Präfix-Suche).
Ergebnis: Nur die Felder, deren Name passt. + nie mit Referenzen, * mit passenden Referenzen.
Wann: Du schaust dir ein Objekt schnell an, etwa im Browser oder mit curl.
GET hat keinen Körper, also auch keine response. CDMS nimmt dann immer ["*"].
Ergebnis: Wie *. Gut zum Ausprobieren, schlecht für Produktion, weil du mehr Daten und mehr Rechte brauchst als nötig.
Wann: Der Benutzer darf employee lesen, company aber nicht.
-
1Client→CDMSschickt
{ "response": ["*"] } -
2CDMS
*nimmtcompanyauf, also muss die Leserolle voncompanyvorhanden sein -
3CDMSDie Rolle fehlt. Die ganze Anfrage scheitert, die Referenz wird nicht einfach weggelassen.
Ergebnis: 403 mit missing-permission|company-read
Die zwei Fallen
Falle 1: null heißt nicht „leer“
In der Antwort steht immer das ganze Objekt. Felder, die du nicht angefordert hast, stehen als null darin, sie fehlen nicht. Bei firstname: null weißt du also nicht, ob das Feld leer ist oder ob du es nur nicht angefordert hast.
Falle 2: * braucht die Rechte aller Referenzen
| response | Rolle employee-read | Rolle company-read | Rolle für department | Antwort |
|---|---|---|---|---|
| ["+"] | ja | – | – | 200 – nur einfache Felder, keine Referenz wird gelesen |
| ["*"] | ja | nein | ja | 403 missing-permission|company-read – die ganze Anfrage scheitert |
| ["*"] | ja | ja | ja | 200 – alles da |
| ["id","firstname"] | ja | – | – | 200 – namentlich angefordert, keine Referenz betroffen |
Ein ["*"], das bei dir funktioniert, kann bei einem Kollegen mit weniger Rollen scheitern.
Warum das Ganze? Die Wirkung auf die Datenbank
Die response ist kein Filter, der hinterher Felder aus der Antwort streicht. Sie bestimmt schon, was aus der Datenbank gelesen wird: CDMS baut eine Abfrage, die genau die angeforderten Spalten liest, und hängt Referenzen per LEFT JOIN an. Ein + auf einem Modell mit 40 Feldern liest also 40 Spalten, ["id", "name"] nur zwei.
flowchart LR
A["response: ['id','firstname','*ment']"] --> B["Expander<br/>→ id, firstname, department.id"]
B --> C["SQL: SELECT e.id, e.firstname, d.id<br/>FROM employee e<br/>LEFT JOIN department d …"]
C --> D["Antwort mit genau diesen Werten"]