Anlegen antwortet mit 201 Created; Schema-Status bei POST ohne Rückgabe richtigstellen #128

Open
opened 2026-10-22 15:57:24 +00:00 by claude · 0 comments
Collaborator

Entschieden am 22.10.2026 beim Zalando-Review von /api/seasons, die Regel steht in CLAUDE.md unter REST-Vertrag.

1. Anlegen antwortet mit 201

Ein POST, der eine neue Ressource anlegt, antwortet mit 201 Created und liefert die neue Ressource wie bisher im Body. So verlangt es Zalando unter „MUST use HTTP methods correctly“, dort als SHOULD formuliert. Gibt es einen GET auf die neue Ressource, steht dessen URL im Location-Header. Heute liefert keiner der Anlege-Endpunkte 201.

Betroffen sind 21 der 46 POSTs:

Bereich Endpunkte
Spielbetrieb /api/seasons, /api/match-weeks, /api/clubs, /api/clubs/{clubId}/players, /api/clubs/{clubId}/teams, /api/players, /api/competition/categories, /api/competition/team-matches/{teamMatchId}/proposals
Turniere /api/competition/tournaments, …/tournaments/categories/{categoryId}/rounds, …/games, …/byes
CMS /api/articles, /api/articles/images, /api/board-members, /api/documents, /api/events, /api/events/{id}/attachments, /api/events/{id}/photos, /api/saisons
Benutzer /api/users

Bei 200 bleiben Aktionen, Importe und Berechnungen:

  • Halbserie fixieren und veröffentlichen
  • archive/unarchive
  • departures, withdraw-options, generate
  • /api/import/*, Elo recalculate/classify/season-start
  • login
  • board-members/{id}/photo (ersetzt das Foto eines bestehenden Eintrags)

Wie Cup-advance (gibt eine nackte Zahl zurück) antworten soll, wird beim Durchgang seines Endpunkts entschieden.

POST /api/competition/categories hat laut Service-Analyse keinen Aufrufer mehr und fällt vielleicht weg. Erst klären, dann umstellen.

Frontends: Hier ändert sich nichts. packages/shared/src/api.ts prüft response.ok, das gilt für 200 wie für 201. Umzustellen sind die Backend- und E2E-Tests, die beim Anlegen 200 erwarten.

Typen: Der Rückgabetyp muss im Schema bleiben (ADR 0007). Prüfen, ob RestResponse<T> oder @ResponseStatus(201) den Typ und die 201 ins openapi.json bringt. Ein rohes Response darf es nicht werden.

2. Das Schema nennt bei 5 POSTs einen falschen Status

Fünf POSTs ohne Rückgabewert stehen in openapi.json mit 201, antworten aber mit 204. SmallRye nimmt für void bei POST 201 an, Quarkus schickt 204, und die Backend-Tests prüfen auf 204:

  • POST /api/auth/change-password
  • POST /api/board-members/reorder
  • POST /api/clubs/{id}/complete
  • POST /api/clubs/{id}/reopen
  • POST /api/competition/elo/corrections

Das Schema muss hier 204 sagen. complete/reopen stehen in der Endpunkt-Überarbeitung ohnehin zur Umstellung auf PUT …/registration-status an. Fallen sie vorher weg, sind es nur noch drei.

Abnahme

  • mvn -B clean verify, die Frontend-Builds, E2E und metrics.py diff sind grün.
  • In openapi.json hat jeder der 21 Anlege-POSTs 201 mit Body-Schema, und kein POST ohne Rückgabe steht mit 201.
  • Gegenprobe: Eine echte Anfrage gegen einen Anlege-Endpunkt liefert 201, im Backend-Test geprüft.
Entschieden am 22.10.2026 beim Zalando-Review von `/api/seasons`, die Regel steht in CLAUDE.md unter *REST-Vertrag*. ## 1. Anlegen antwortet mit 201 Ein POST, der eine neue Ressource anlegt, antwortet mit **201 Created** und liefert die neue Ressource wie bisher im Body. So verlangt es Zalando unter „MUST use HTTP methods correctly“, dort als SHOULD formuliert. Gibt es einen GET auf die neue Ressource, steht dessen URL im `Location`-Header. Heute liefert keiner der Anlege-Endpunkte 201. Betroffen sind 21 der 46 POSTs: | Bereich | Endpunkte | |---|---| | Spielbetrieb | `/api/seasons`, `/api/match-weeks`, `/api/clubs`, `/api/clubs/{clubId}/players`, `/api/clubs/{clubId}/teams`, `/api/players`, `/api/competition/categories`, `/api/competition/team-matches/{teamMatchId}/proposals` | | Turniere | `/api/competition/tournaments`, `…/tournaments/categories/{categoryId}/rounds`, `…/games`, `…/byes` | | CMS | `/api/articles`, `/api/articles/images`, `/api/board-members`, `/api/documents`, `/api/events`, `/api/events/{id}/attachments`, `/api/events/{id}/photos`, `/api/saisons` | | Benutzer | `/api/users` | Bei 200 bleiben Aktionen, Importe und Berechnungen: - Halbserie fixieren und veröffentlichen - `archive`/`unarchive` - `departures`, `withdraw-options`, `generate` - `/api/import/*`, Elo `recalculate`/`classify`/`season-start` - `login` - `board-members/{id}/photo` (ersetzt das Foto eines bestehenden Eintrags) Wie Cup-`advance` (gibt eine nackte Zahl zurück) antworten soll, wird beim Durchgang seines Endpunkts entschieden. `POST /api/competition/categories` hat laut Service-Analyse keinen Aufrufer mehr und fällt vielleicht weg. Erst klären, dann umstellen. **Frontends:** Hier ändert sich nichts. `packages/shared/src/api.ts` prüft `response.ok`, das gilt für 200 wie für 201. Umzustellen sind die Backend- und E2E-Tests, die beim Anlegen `200` erwarten. **Typen:** Der Rückgabetyp muss im Schema bleiben (ADR 0007). Prüfen, ob `RestResponse<T>` oder `@ResponseStatus(201)` den Typ und die 201 ins `openapi.json` bringt. Ein rohes `Response` darf es nicht werden. ## 2. Das Schema nennt bei 5 POSTs einen falschen Status Fünf POSTs ohne Rückgabewert stehen in `openapi.json` mit **201**, antworten aber mit **204**. SmallRye nimmt für `void` bei POST 201 an, Quarkus schickt 204, und die Backend-Tests prüfen auf 204: - `POST /api/auth/change-password` - `POST /api/board-members/reorder` - `POST /api/clubs/{id}/complete` - `POST /api/clubs/{id}/reopen` - `POST /api/competition/elo/corrections` Das Schema muss hier 204 sagen. `complete`/`reopen` stehen in der Endpunkt-Überarbeitung ohnehin zur Umstellung auf `PUT …/registration-status` an. Fallen sie vorher weg, sind es nur noch drei. ## Abnahme - `mvn -B clean verify`, die Frontend-Builds, E2E und `metrics.py diff` sind grün. - In `openapi.json` hat jeder der 21 Anlege-POSTs `201` mit Body-Schema, und kein POST ohne Rückgabe steht mit `201`. - **Gegenprobe:** Eine echte Anfrage gegen einen Anlege-Endpunkt liefert 201, im Backend-Test geprüft.
Sign in to join this conversation.
No description provided.