Bei der Entwicklung von HTTP-APIs ist die Fehlerbehandlung oft ein mühsamer Teil. Je mehr APIs es gibt und je komplexer die interne Logik wird, desto mehr Schwierigkeiten treten in drei Aspekten auf.
- Rückgabe geeigneter Fehlercodes: Für Entwickler mit wenig Erfahrung ist es in komplexer Logik schwierig, konsistente HTTP-Statuscodes zu verwenden.
- Schreiben großer Mengen an Ergebnis-Logs: Bei jedem erwarteten Abbruchpunkt im Fehlerfall Logs zu hinterlegen, vergrößert den Codeumfang und macht die Verwaltung komplexer.
- Übermittlung klarer Fehlermeldungen: Wenn dem Client nur eine einfache Fehlermeldung übergeben wird, ist es schwierig, den Fehler klar zu verstehen und zu verarbeiten.
Verbesserung bei der Rückgabe geeigneter Fehlercodes
Um das Problem inkonsistenter Verwendung von Fehlercodes zu lösen, wird vorgeschlagen, ein HttpError-Interface oder eine entsprechende Struktur zu implementieren, die StatusCode und Message enthält.
- Lösung:
- Definition des Typs
HttpError: Kapselt HTTP-Statuscode und Nachricht. - Bereitstellung von Helper-Funktionen: Mit Helper-Funktionen, die bestimmte Fehlercodes zurückgeben, wie
httperror.BadRequest("wrong format"), lassen sich Fehlerobjekte einfach erzeugen.
- Definition des Typs
- Vorteile:
- Bequeme und sichere Eingabe von Fehlercodes und Nachrichten durch Nutzung der Autovervollständigung der IDE.
- Geringere Fehlerwahrscheinlichkeit als bei der manuellen Eingabe numerischer Codes.
- Weniger Aufwand durch das ständige Nachschlagen vorbereiteter Designdokumente.
Zentralisierung des Loggings
Um wiederholtes Schreiben von Logs zu reduzieren und die Fehlerbehandlungslogik an einer Stelle zu verwalten, wird eine Methode zum Wrappen von HTTP-Handlern vorgestellt.
- Lösung:
- Implementierung eines Custom-Routers (
chiwrap.Router): Ein bestehender Router wiechi.Routerwird intern eingebunden und um Fehlerbehandlungslogik erweitert. - Handler-Wrapping: Methoden des Custom-Routers wie
GetnehmenHandlerFuncentgegen, führen sie intern aus und leiten auftretende Fehler an eine zentrale Behandlungslogik weiter. - Fehler-Callback-Funktion: Beim Erzeugen mit
NewRouterwird eineerrCallback-Funktion entgegengenommen, die im Fehlerfall aufgerufen wird, um zentral Logs zu schreiben oder zusätzliche Verarbeitung auszuführen.
- Implementierung eines Custom-Routers (
- Vorteile:
- Tritt in der API-Logik ein Fehler auf, werden automatisch passende Fehlercodes und Nachrichten als Antwort zurückgegeben.
- Durch das Registrieren einer Callback-Funktion, die je nach Service passende Logs schreibt, wird die Log-Verwaltung erleichtert.
- Weniger Code-Duplizierung und bessere Wartbarkeit.
Übermittlung klarer Fehlermeldungen (mit RFC7807)
Damit Clients Fehler klarer verstehen und verarbeiten können, wird vorgeschlagen, strukturierte Fehlermeldungen mithilfe des RFC7807-Standards zu übertragen.
- Wichtige Elemente von RFC7807:
type: URI zur Identifikation des Fehlertyps (z. B.https://example.com/errors/validation).title: Kurze einzeilige Beschreibung des Fehlers.status: Entspricht dem HTTP-Statuscode.detail: Für Menschen lesbare ausführliche Fehlerbeschreibung.instance: Konkrete URI, bei der der Fehler aufgetreten ist (z. B./api/users/abc).extensions: JSON-Objekt für zusätzliche Informationen (z. B.invalid_field,expected_format).
- Implementierung:
-
Erstellung einer Struktur
RFC7807Errormit den wichtigsten Elementen. -
Einfache Erzeugung strukturierter Fehlerobjekte über ein Method-Chaining-Muster (
WithType(),WithInstance(),WithExtension()). -
Über die Methode
ToHttpError()kannRFC7807ErrorinHttpErrorumgewandelt und damit an den zentralisierten Router angebunden werden. -
Clients können Art, Ursache und Auftretensort des Fehlers klar erkennen.
-
Die Konsistenz und Nützlichkeit von API-Antworten steigen, was die Effizienz der Client-Entwicklung verbessert.
-
5 Kommentare
Vielen Dank für den guten Artikel.
Vielen Dank für den guten Artikel!
Zur Referenz: In Spring gibt es im
spring-web-Paket unterorg.springframework.http.ProblemDetaileine Implementierung!Vielen Dank für die gute Einführung!
Wie ich nachgesehen habe, wurde sie durch RFC 9457 ersetzt.
https://datatracker.ietf.org/doc/html/rfc9457
(bisheriges 7807-Dokument: https://datatracker.ietf.org/doc/html/rfc7807)
Die wichtigsten Unterschiede zwischen RFC 7807 und RFC 9457
errorspointeroffiziellFür neue Projekte seit Juli 2023 wird empfohlen, RFC 9457 anzuwenden
Es scheint empfohlen zu sein, das Feld
typeals dereferenzierbare URI festzulegen.Bei internen Services dürfte es auch in Ordnung sein, stattdessen einen Link zur Swagger-UI-Dokumentation zu verwenden.