Strukturierte Fehlermeldungen für HTTP APIs
November 2, 2022
Seit ich an dem Apache APISIX-Projekt arbeite, versuche ich, mein Wissen und Verständnis von REST RESTful HTTP-APIs zu verbessern. Dafür lese und sehe ich mir die folgenden Quellen an:
- Bücher. Derzeit beende ich API Design Patterns. Eine Rezension wird bald folgen.
- YouTube. Ich empfehle ErikWildes Kanal. Während einige Videos besser sind als andere, konzentrieren sie sich alle auf APIs.
- IETF RFCs. Die meisten RFCs handeln nicht von APIs, aber eine freundliche Person hat eine Liste der relevanten RFCs zusammengestellt.
Heute möchte ich das RFC "Problem Details for HTTP APIs" vorstellen, auch bekannt als RFC 7807.
Das Problem (oder die Probleme)
REST-Prinzipien schreiben vor, HTTP-Statuscodes zur Kommunikation zu verwenden. Für Fehler definiert HTTP zwei Bereiche: Client-Fehler, 4xx
, und Server-Fehler, 5xx
.
Stellen Sie sich eine Banking-API vor, die Überweisungen ermöglicht. Sie sollte fehlschlagen, wenn Sie versuchen, mehr Geld auf Ihr Konto zu überweisen. Einige HTTP-Statuscodes könnten passen:
400 Bad Request
: Der Server kann oder will die Anfrage aufgrund eines wahrgenommenen Client-Fehlers nicht verarbeiten.402 Payment Required
: Die Anfrage kann erst verarbeitet werden, wenn der Client eine Zahlung leistet. Es gibt jedoch keine Standardkonvention für die Verwendung, und verschiedene Entitäten verwenden ihn in anderen Kontexten.409 Conflict
: Die Anfrage steht im Konflikt mit dem aktuellen Zustand der Zielressource.
Hier ist das erste Problem: HTTP-Statuscodes wurden für Mensch-zu-Maschine-Interaktionen über Browser spezifiziert, nicht für Maschine-zu-Maschine-Interaktionen über APIs. Daher ist die Auswahl eines Statuscodes, der eins zu eins auf den Anwendungsfall abbildet, selten einfach. Zur Information: Martin Fowler scheint in unserem Fall 409 zu bevorzugen.
Unabhängig vom Statuscode betrifft das zweite Problem die Fehlernutzlast oder genauer gesagt ihre Struktur. Die Struktur ist unwichtig, wenn eine einzelne Organisation den Client und den API-Anbieter verwaltet. Selbst wenn ein dediziertes Team jeden von ihnen entwickelt, können sie sich abstimmen. Stellen Sie sich beispielsweise eine mobile App vor, die ihre eigene API aufruft.
Probleme entstehen jedoch, wenn ein Team beschließt, eine Drittanbieter-API zu verwenden. Die Wahl der Antwortstruktur ist in diesem Fall von Bedeutung, da sie nun als Teil eines Vertrags betrachtet wird: Jede Änderung des Anbieters kann die Clients brechen. Schlimmer noch, die Struktur ist wahrscheinlich von Anbieter zu Anbieter unterschiedlich.
Daher bietet eine standardisierte Fehlerberichtsstruktur:
- Einheitlichkeit über Anbieter hinweg
- Erhöhte API-Stabilität
RFC 7807
RFC 7807 zielt darauf ab, das Problem zu lösen, indem es eine standardisierte Fehlerstruktur bereitstellt.
Die Struktur sieht wie folgt aus:
Das RFC beschreibt die Felder:
"type"
(string
) - Ein URI-Referenz [RFC3986], die den Problemtyp identifiziert. Diese Spezifikation empfiehlt, dass beim Dereferenzieren eine menschenlesbare Dokumentation für den Problemtyp bereitgestellt wird (z.B. unter Verwendung von HTML [W3C.REC-html5-20141028]). Wenn dieses Mitglied nicht vorhanden ist, wird sein Wert als"about:blank"
angenommen."title"
(string
) - Eine kurze, menschenlesbare Zusammenfassung des Problemtyps. Es SOLLTE sich von Auftreten zu Auftreten des Problems nicht ändern, außer zu Lokalisierungszwecken (z.B. unter Verwendung von proaktiver Inhaltsverhandlung; siehe [RFC7231, Abschnitt 3.4])."status"
(number
) - Der ([RFC7231], Abschnitt 6) vom Ursprungsserver für dieses Auftreten des Problems generierte Statuscode."detail"
(string
) - Eine menschenlesbare Erklärung, die spezifisch für dieses Auftreten des Problems ist."instance"
(string
) - Ein URI-Referenz, der das spezifische Auftreten des Problems identifiziert. Es kann bei Dereferenzierung weitere Informationen liefern oder auch nicht.
Das RFC bietet das folgende Beispiel, wenn nicht genügend Guthaben für eine Banküberweisung vorhanden ist.
Ein Beispiel
Ich werde eines meiner bestehenden Demos als Beispiel verwenden. Die Demo hebt mehrere Schritte hervor, um den Prozess der API-Evolution zu erleichtern.
In Schritt 6 möchte ich, dass sich Benutzer registrieren, daher begrenze ich die Anzahl der Aufrufe in einem Zeitfenster, wenn sie nicht authentifiziert sind. Ich habe dafür ein dediziertes Apache-APISIX-Plugin erstellt. Nachdem die Anzahl der Aufrufe das Limit erreicht hat, gibt es Folgendes zurück:
HTTP/1.1 429 Too Many Requests
Date: Fri, 28 Oct 2022 11:56:11 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.15.0
{"error_msg":"Please register at https:\/\/apisix.org\/register to get your API token and enjoy unlimited calls"}
Lassen Sie uns die Nachricht gemäß RFC 7807 strukturieren.
Fazit
RFC 7807 hilft nicht nur Client-Entwicklern. Es ist eine enorme Hilfe für API-Implementierer, da es schnelle Richtlinien bietet, um das Rad nicht bei jedem Projekt neu zu erfinden.
Weiterführende Informationen:
Ursprünglich veröffentlicht auf A Java Geek am 30. Oktober 2022