REST API Design & Fehlerverträge
Ressourcen, DTOs, Statuscodes, Problem Details, Versionierung, Pagination und Idempotency-Key.
Version 3IntegrationCodeDiagramm
In dieser Datei
REST ist ein Vertrag
REST APIs sind langlebige Verträge. Sie brauchen klare Ressourcen, Statuscodes, Fehlerformat, Security, Versionierung und Beispiele. Controller-Code ist nur die technische Oberfläche dieses Vertrags.
Problem Details im Enterprise-Kontext
Clients müssen unterscheiden können: Eingabe ungültig, Objekt nicht gefunden, fachlicher Konflikt, technische Störung, temporärer Fehler. Ein einheitliches Fehlerformat senkt Integrationsaufwand.
Idempotenz für kritische Kommandos
Bei Bestellung, Zahlung, Storno oder Buchung muss ein Retry ungefährlich sein. Ein Idempotency-Key verhindert doppelte Effekte.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
Problem Details Beispiel
{
"type": "https://errors.example.com/order/credit-limit-exceeded",
"title": "Credit limit exceeded",
"status": 409,
"detail": "Customer C-4711 cannot place an order above 5000 EUR.",
"traceId": "4f7b9c0e6d2a",
"violations": []
}
Idempotent Command Handling
public IdResponse place(String idempotencyKey, PlaceOrderRequest request) {
return idempotencyStore.executeOnce(idempotencyKey, () -> {
OrderId id = placeOrder.place(request.toCommand());
return new IdResponse(id.value());
});
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Immer 200 OK | Clients können Fehler nicht automatisiert behandeln. |
| Unbegrenzte Listen | Performance und Speicher kippen bei echten Daten. |
| Entity als Response | API wird an Datenbankmodell gekoppelt. |