22 Punkte von lemonmint 2025-06-02 | 5 Kommentare | Auf WhatsApp teilen

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.
  • 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 wie chi.Router wird intern eingebunden und um Fehlerbehandlungslogik erweitert.
    • Handler-Wrapping: Methoden des Custom-Routers wie Get nehmen HandlerFunc entgegen, führen sie intern aus und leiten auftretende Fehler an eine zentrale Behandlungslogik weiter.
    • Fehler-Callback-Funktion: Beim Erzeugen mit NewRouter wird eine errCallback-Funktion entgegengenommen, die im Fehlerfall aufgerufen wird, um zentral Logs zu schreiben oder zusätzliche Verarbeitung auszuführen.
  • 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 RFC7807Error mit den wichtigsten Elementen.

    • Einfache Erzeugung strukturierter Fehlerobjekte über ein Method-Chaining-Muster (WithType(), WithInstance(), WithExtension()).

    • Über die Methode ToHttpError() kann RFC7807Error in HttpError umgewandelt 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

 
aer0700 2025-06-02

Vielen Dank für den guten Artikel.

 
beoks 2025-06-02

Vielen Dank für den guten Artikel!
Zur Referenz: In Spring gibt es im spring-web-Paket unter org.springframework.http.ProblemDetail eine Implementierung!

 
honglu 2025-06-02

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)

 
findnamo 2025-06-02

Die wichtigsten Unterschiede zwischen RFC 7807 und RFC 9457

  • Verwaltung von Problemtypen: 7807 erlaubt nur benutzerdefinierte URIs, 9457 führt ein gemeinsames IANA-Register ein
  • Behandlung mehrerer Fehler: 7807 empfiehlt die Verwendung des HTTP-Statuscodes 207, 9457 gruppiert zusammengehörige Fehler innerhalb eines einzelnen Problemtyps mithilfe des Arrays errors
  • Erweiterungsfelder: 7807 erlaubt das Hinzufügen beliebiger Felder, 9457 verknüpft explizit die je Problemtyp erwarteten Felder
  • Sicherheitsempfehlungen: 7807 enthält keine, 9457 ergänzt ausdrückliche Richtlinien zur Vermeidung von Sicherheitslücken
  • JSON Pointer: 7807 unterstützt dies nicht, 9457 unterstützt das Feld pointer offiziell

Für neue Projekte seit Juli 2023 wird empfohlen, RFC 9457 anzuwenden

 
honglu 2025-06-02

Es scheint empfohlen zu sein, das Feld type als dereferenzierbare URI festzulegen.

Bei internen Services dürfte es auch in Ordnung sein, stattdessen einen Link zur Swagger-UI-Dokumentation zu verwenden.