Entscheidungsbaum
Beginne hier und folge dem Pfad, der zu deiner Situation passt.
War die Anfrage erfolgreich?
Ja und ich gebe Daten zurück -> 200 OK
Standard-Erfolgsantwort. Verwende für GET-Anfragen, die Daten zurückgeben, POST-Anfragen, die Aktionen ausführen, und PUT/PATCH-Anfragen, die aktualisieren und das Ergebnis zurückgeben.
Ja und ich habe eine neue Ressource erstellt -> 201 Created
Verwende nach POST oder PUT, das etwas Neues erstellt hat. Füge einen Location-Header mit der URL der neuen Ressource hinzu.
Ja, aber es gibt keinen Körper zurückzugeben -> 204 No Content
Verwende für erfolgreiche DELETE-Anfragen oder PUT/PATCH, bei denen der Client die aktualisierte Ressource nicht benötigt. Die Antwort hat keinen Körper.
Ja, aber ich habe das schon einmal gemacht -> 200 OK oder 204 No Content
Für idempotente Operationen (PUT, DELETE), bei denen der Endzustand unabhängig davon, wie oft aufgerufen wird, derselbe ist, gib denselben Erfolgscode wie beim ersten Aufruf zurück.
Angenommen, aber noch nicht abgeschlossen -> 202 Accepted
Verwende, wenn der Server die Anfrage zur asynchronen Verarbeitung in die Warteschlange gestellt hat. Der Client muss später pollend oder einen Callback erhalten. Gut für lange Aufgaben, Batch-Operationen oder Webhook-Zustellungen.
Muss der Client woanders hingehen?
Permanente Änderung -> 301 Moved Permanently
Die Ressource hat dauerhaft eine neue URL. Browser und Suchmaschinen aktualisieren ihre Aufzeichnungen. Sicher für GET-Anfragen. Hinweis: Einige ältere Clients ändern POST zu GET bei der Weiterleitung.
Permanente Änderung, Methode beibehalten -> 308 Permanent Redirect
Wie 301, stellt aber sicher, dass die HTTP-Methode beibehalten wird. Ein POST bleibt POST. Verwende, wenn die Methodenerhaltung wichtig ist (API-Weiterleitungen).
Temporäre Änderung -> 302 Found
Die Ressource ist vorübergehend unter einer anderen URL. Browser cachen für die Session, überprüfen aber später erneut. In der Praxis die häufigste temporäre Weiterleitung.
Temporäre Änderung, Methode beibehalten -> 307 Temporary Redirect
Wie 302, bewahrt aber die HTTP-Methode. Verwende für temporäre API-Weiterleitungen, bei denen ein POST ein POST bleiben muss.
Andere anzeigen -> 303 See Other
Verwende nach einem POST, um den Client zu einem GET-Endpunkt weiterzuleiten. Häufiges Muster: POST /orders gibt 303 mit Location: /orders/123 zurück, dann macht der Client GET für die neue Bestellung.
Liegt das Problem auf Client-Seite?
Fehlerhafte Anfrage -> 400 Bad Request
Die Syntax der Anfrage ist falsch. Ungültiges JSON, fehlender Content-Type, nicht dekodierbarer Körper. Der Client muss die Anfrage korrigieren, bevor er es erneut versucht.
Nicht authentifiziert -> 401 Unauthorized
Keine Credentials angegeben, oder die Credentials sind abgelaufen/ungültig. Der Client muss sich authentifizieren (Login, Refresh-Token) und es erneut versuchen.
Authentifiziert, aber keine Berechtigung -> 403 Forbidden
Der Server weiß, wer der Client ist, aber er hat keine Berechtigung. Erneute Authentifizierung hilft nicht. Überprüfe Rollen/Berechtigungen.
Ressource existiert nicht -> 404 Not Found
Die URL entspricht keiner Ressource. Wird auch häufig verwendet, um die Existenz von Ressourcen zu verbergen, die der Client nicht kennen darf (anstelle von 403).
Falsche HTTP-Methode -> 405 Method Not Allowed
Der Endpunkt existiert, unterstützt aber diese Methode nicht. Beispiel: DELETE auf einem schreibgeschützten Endpunkt. Füge einen Allow-Header mit den gültigen Methoden hinzu.
Konflikt mit aktuellem Zustand -> 409 Conflict
Die Anfrage steht im Konflikt mit dem aktuellen Zustand der Ressource. Häufige Verwendungen: doppelte Erstellungsversuche, fehlgeschlagenes optimistisches Locking (divergierende Version), Zustandsmaschinenverletzungen (versuchen, einen bereits veröffentlichten Beitrag zu veröffentlichen).
Ressource wurde entfernt -> 410 Gone
Wie 404, aber der Server weiß, dass diese Ressource zuvor existiert hat und absichtlich entfernt wurde. Stärkeres Signal als 404 für Suchmaschinen und Caching.
Validierungsfehler -> 422 Unprocessable Entity
Die Syntax ist gültig (es ist korrektes JSON), aber der Inhalt ist falsch. Fehlende Pflichtfelder, falsche Datentypen, Werte außerhalb des Bereichs. Verwende für Validierungsfehler der Geschäftslogik.
Zu viele Anfragen -> 429 Too Many Requests
Ratelimiting. Füge einen Retry-After-Header hinzu, der dem Client mitteilt, wann er es erneut versuchen soll.
Liegt das Problem auf Server-Seite?
Unerwarteter Serverfehler -> 500 Internal Server Error
Etwas ist kaputt. Unbehandelte Ausnahme, Nullzeiger, Konfigurationsfehler. Das Standard-Fangnetz für “das ist unser Fehler.” Protokolliere den Fehler, lege keine internen Details gegenüber dem Client offen.
Nicht implementiert -> 501 Not Implemented
Der Server unterstützt diese Funktionalität nicht. Verwende für Endpunkte, die definiert, aber noch nicht gebaut sind, oder für HTTP-Methoden, die der Server nicht erkennt.
Upstream-Dienst fehlgeschlagen -> 502 Bad Gateway
Der Server fungiert als Proxy/Gateway und hat eine ungültige Antwort vom Upstream-Dienst erhalten. Häufig bei Load-Balancern und Reverse-Proxys, wenn ein Backend ausfällt.
Dienst überlastet oder in Wartung -> 503 Service Unavailable
Der Server kann die Anfrage jetzt nicht bearbeiten. Kann überlastet, in Wartung oder beim Hochfahren sein. Füge einen Retry-After-Header hinzu, wenn du weißt, wann er zurückkommt.
Upstream-Timeout -> 504 Gateway Timeout
Der Server fungiert als Proxy und der Upstream hat nicht rechtzeitig geantwortet. Anders als 408 (Client-Timeout): 504 bedeutet, dass der eigene Upstream des Servers das Zeitlimit überschritten hat.
Kurzreferenztabelle
Erfolg (2xx)
| Code | Name | Wann verwenden |
|---|---|---|
| 200 | OK | Standard-Erfolg, Daten zurückgeben |
| 201 | Created | Neue Ressource erstellt (Location-Header einfügen) |
| 202 | Accepted | Asynchrone Verarbeitung gestartet |
| 204 | No Content | Erfolg, kein Körper (DELETE, PUT fire-and-forget) |
Weiterleitung (3xx)
| Code | Name | Methode erhalten? | Permanente? |
|---|---|---|---|
| 301 | Moved Permanently | Nein (kann zu GET wechseln) | Ja |
| 302 | Found | Nein (kann zu GET wechseln) | Nein |
| 303 | See Other | Wechselt immer zu GET | N/A |
| 307 | Temporary Redirect | Ja | Nein |
| 308 | Permanent Redirect | Ja | Ja |
Client-Fehler (4xx)
| Code | Name | Wann verwenden |
|---|---|---|
| 400 | Bad Request | Fehlerhafte Syntax |
| 401 | Unauthorized | Credentials fehlen oder ungültig |
| 403 | Forbidden | Authentifiziert, aber keine Berechtigung |
| 404 | Not Found | Ressource existiert nicht |
| 405 | Method Not Allowed | Falsche HTTP-Methode |
| 409 | Conflict | Zustandskonflikt (Duplikate, divergierende Version) |
| 410 | Gone | Ressource dauerhaft entfernt |
| 422 | Unprocessable Entity | Syntax gültig, Daten ungültig |
| 429 | Too Many Requests | Ratelimit überschritten |
Server-Fehler (5xx)
| Code | Name | Wann verwenden |
|---|---|---|
| 500 | Internal Server Error | Unbehandelter Serverfehler |
| 502 | Bad Gateway | Upstream hat ungültige Antwort zurückgegeben |
| 503 | Service Unavailable | Überlastet oder in Wartung |
| 504 | Gateway Timeout | Upstream hat nicht rechtzeitig geantwortet |
Häufige API-Muster
REST-CRUD-Operationen
| Operation | Methode | Erfolgscode | Fehlercodes |
|---|---|---|---|
| Ressourcen auflisten | GET | 200 | 401, 403 |
| Ressource abrufen | GET | 200 | 401, 403, 404 |
| Ressource erstellen | POST | 201 | 400, 401, 403, 409, 422 |
| Vollständige Aktualisierung | PUT | 200 oder 204 | 400, 401, 403, 404, 422 |
| Teilaktualisierung | PATCH | 200 oder 204 | 400, 401, 403, 404, 422 |
| Ressource entfernen | DELETE | 204 | 401, 403, 404 |
Header, die du einfügen solltest
| Statuscode | Empfohlener Header |
|---|---|
| 201 | Location: /resource/id |
| 301, 302, 307, 308 | Location: https://new-url |
| 405 | Allow: GET, POST |
| 429 | Retry-After: 60 |
| 503 | Retry-After: 300 |