CodamAIDocs
Themafertig

Wildcards + und *

Wie du mit + und * viele Felder auf einmal anforderst, was die Teil-Wildcards name+, +name, name* und *name treffen und warum * mehr Rechte braucht, als man denkt.

Ausprägungen
+ allein* alleinPräfix: name+ / name*Suffix: +name / *nameKombination mehrerer EinträgeexcludeWildcard ohne TrefferMarker in der WortmitteGET /read = ** ohne Leserecht auf Referenz

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:

ZeichenMerkhilfeliefert
+„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):

FeldArtBeispielwert
ideinfach"7f3…"
firstnameeinfach"Daniel"
lastnameeinfach"Mertins"
companyReferenz auf company{ "id": "a1…" }
departmentReferenz auf department{ "id": "d4…" }

Die zwei Grundformen

+ und * am Modell employee
einfaches FeldReferenzwird geliefert
AnfrageErgebnis
["+"]
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.
Dieselbe Anfrage mit * als Request und Response
Anfrage
POST /api/rest/hr/employee/read/7f3…
{ "response": ["*"] }
Antwort
{
  "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:

Formliest sich alstrifft
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 beginnenPräfix
*namewie +name, plus Referenzen, die auf name endenSuffix
Alle Teil-Wildcards am Modell employee
einfaches FeldReferenzwird geliefert
AnfrageErgebnis
["+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:

  1. Wortanfang oder Wortende, sonst nichts. Es gibt keine regulären Ausdrücke, kein Zeichen in der Wortmitte und nie zwei Zeichen in einem Eintrag.
  2. Groß- und Kleinschreibung zählen. +Name trifft firstname nicht.
  3. Mehrere Einträge werden zusammengezählt. ["+name", "*ment"] liefert firstname, lastname und department.
  4. 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:

Anfrage
{ "response": ["*"], "exclude": ["department"] }
Antwort
{ "data": { "id": "7f3…", "firstname": "Daniel",
            "lastname": "Mertins", "company": { "id": "a1…" },
            "department": null } }
Wann wirkt exclude?
wirkt
  • auf Felder, die durch eine Wildcard dazugekommen sind
  • ["*"] + exclude: ["department"] → department fehlt
wirkt nicht
  • auf Felder, die du namentlich angefordert hast
  • ["department", "+"] + exclude: ["department"] → department ist trotzdem da

Alle Ausprägungen auf einen Blick

Was bei welcher Anfrage passiert

Wann: Du brauchst alle einfachen Felder und keine Referenzen.

  1. 1
    Client→CDMS
    schickt { "response": ["+"] }
  2. 2
    CDMS
    nimmt alle einfachen Felder des Modells auf
  3. 3
    CDMS→Datenbank
    liest 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.

  1. 1
    Client→CDMS
    schickt { "response": ["*"] }
  2. 2
    CDMS
    nimmt alle einfachen Felder und alle Referenzen auf
  3. 3
    CDMS
    prüft für jede Referenz die Leserolle des referenzierten Modells
  4. 4
    CDMS→Datenbank
    liest 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.

  1. 1
    Client→CDMS
    schickt { "response": ["*"] }
  2. 2
    CDMS
    * nimmt company auf, also muss die Leserolle von company vorhanden sein
  3. 3
    CDMS
    Die 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

Anfrage auf employee – wer bekommt was?
responseRolle employee-readRolle company-readRolle für departmentAntwort
["+"]ja––200 – nur einfache Felder, keine Referenz wird gelesen
["*"]janeinja403 missing-permission|company-read – die ganze Anfrage scheitert
["*"]jajaja200 – 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"]
Quellen im Code und in der Wissensdatenbank
  • documentation/05-api-guide/04-lesen.md
  • documentation/20-api/03-response-requests.md
  • CDMS/cdms-rest-api – Expander
Suchen