Zum Inhalt springen

Response Requests – welche Felder kommen zurück?

Kurzantwort: In jedem Payload steht eine response-Liste. Sie bestimmt, welche Felder die Antwort enthält – und damit auch, was überhaupt aus der Datenbank geladen wird. + steht für alle skalaren Felder, * zusätzlich für alle Referenzen (jeweils nur mit id). Referenzen lassen sich mit einem verschachtelten Objekt gezielt ausbauen. Eine fehlende response ist ein Fehler.


  • kein Overfetching – es wird genau selektiert, was angefragt ist
  • keine unkontrollierte Tiefenladung über den ganzen Objektgraphen
  • der Client entscheidet, der Server erlaubt
  • die Feldprojektion greift bis in die SQL-Abfrage durch (Tuple-Projektion)
{ "response": ["id", "name", "createdAt"] }
WildcardWirkung
+alle skalaren Felder
*alle skalaren Felder und alle Referenzen, letztere nur mit id
+suffix / *suffixalle Felder, deren Name auf suffix endet
prefix+ / prefix*alle Felder, deren Name mit prefix beginnt
{ "response": ["*"] }
{ "response": ["+", "name*"] }

GET /read/{id} verwendet intern immer ["*"].

{ "response": ["*"], "exclude": ["internalComment", "secretValue"] }

exclude wirkt auf die Wildcard-Expansion: ausgeschlossene Felder werden weder als skalares Feld noch als Referenz aufgenommen.

Eine Referenz wird über ein Objekt mit field und eigener response ausgebaut:

{
"response": [
"id", "name",
{
"field": "orders",
"response": ["id", "total", {"field": "items", "response": ["+"]}],
"parameter": {
"limit": 5,
"page": 0,
"order": [{"field": "total", "order": "DESC"}],
"query": {
"type": "AND",
"filter": [{"key": "status", "value": "OPEN", "param": "EQ"}]
}
}
}
]
}

Für Listenreferenzen ist parameter erlaubt – mit Filter, Sortierung und Pagination wie bei einer eigenständigen Abfrage. CDMS ergänzt automatisch den Filter auf die Rückreferenz (<backReference>.id = <id des Elternobjekts>).

flowchart TB
    A["response aus dem Payload"] --> B{Eintrag}
    B -->|String ohne Wildcard| C["Feld direkt übernehmen"]
    B -->|"'+' oder Muster mit +"| D["alle passenden skalaren Felder"]
    B -->|"'*' oder Muster mit *"| E["skalare Felder<br/>+ Referenzen mit nur 'id'"]
    B -->|"ModelResponse (field + response)"| F["rekursiv expandieren<br/>je konkretem Untertyp"]
    C --> G["RequestSingle/RequestQuery:<br/>fields · models · lists"]
    D --> G
    E --> G
    F --> G
    G --> H["Persistenz: Tuple-Projektion<br/>lädt genau diese Spalten"]

Der Expander (cdms-rest-api) zerlegt die response in drei Töpfe:

TopfInhalt
fieldsskalare Felder
modelsEinzelreferenzen, je mit eigenem Unter-Request
listsListenreferenzen, je mit eigenem Unter-Request und parameter

Er schreibt die expandierte Liste zusätzlich in die response zurück – die Antwort spiegelt also, was aus der Anfrage geworden ist.

Zeigt ein Feld auf ein abstraktes Modell, löst der Expander es für jeden konkreten Untertyp auf und vereinigt die Ergebnisse. Ein + in einer solchen verschachtelten Anfrage bedeutet damit „alle skalaren Felder aller möglichen Untertypen”. Der Unter-Request wird nur einmal an die Elternantwort gehängt.

SituationVerhalten
response fehlt ganzInvalidQueryDefinitionException (400)
unbekanntes Feld in einer verschachtelten Anfragewird protokolliert und übersprungen
Feld ist kein Beziehungsfeld, wird aber als ModelResponse angefragtprotokolliert, übersprungen
Feld ohne Leserechtim Strict Mode Fehler, sonst still weggelassen

Der Response Request ist keine Nachbearbeitung, sondern steuert die Abfrage: Die Persistenz baut eine CriteriaQuery<Tuple> mit genau den angefragten Spalten, Referenzen werden mit LEFT JOIN angebunden (damit Objekte ohne Beziehung nicht herausfallen), und die Aliase in Punktschreibweise (customer.id) werden wieder zu einer verschachtelten Struktur zusammengesetzt. Es findet kein Lazy Loading während des Mappings statt.