Le traitement des erreurs est souvent une partie fastidieuse lors du développement d’une API HTTP. À mesure que le nombre d’API augmente et que la logique interne se complexifie, des difficultés apparaissent sous trois aspects.
- Retourner des codes d’erreur appropriés : pour les développeurs moins expérimentés, il est difficile d’utiliser des codes de statut HTTP cohérents dans une logique complexe.
- Écrire un grand volume de logs de résultat : consigner des logs à tous les points de sortie attendus lorsqu’une erreur survient augmente la quantité de code et complique sa gestion.
- Envoyer des messages d’erreur clairs : transmettre simplement un message d’erreur au client ne suffit pas pour comprendre et traiter clairement l’erreur.
Améliorer le retour de codes d’erreur appropriés
Pour résoudre le problème de cohérence dans l’utilisation des codes d’erreur, il est proposé d’implémenter une interface ou une structure HttpError incluant StatusCode et Message.
- Solution :
- Définir le type
HttpError: encapsule le code de statut HTTP et le message. - Fournir des fonctions utilitaires : utiliser des fonctions utilitaires qui retournent un code d’erreur spécifique, comme
httperror.BadRequest("wrong format"), afin de créer facilement des objets d’erreur.
- Définir le type
- Avantages :
- Saisir les codes d’erreur et messages de manière pratique et fiable grâce à l’autocomplétion de l’IDE.
- Réduire le risque d’erreur par rapport à la saisie manuelle de codes numériques.
- Réduire la contrainte de devoir vérifier à chaque fois la documentation de conception préparée à l’avance.
Centraliser l’écriture des logs
Pour réduire l’écriture répétitive de logs et gérer la logique de traitement des erreurs en un seul endroit, il est proposé d’utiliser une approche consistant à envelopper le gestionnaire HTTP.
- Solution :
- Implémenter un routeur personnalisé (
chiwrap.Router) : intégrer en interne un routeur existant commechi.Routeret y ajouter la logique de traitement des erreurs. - Envelopper le handler : les méthodes du routeur personnalisé comme
Getreçoivent unHandlerFunc, l’exécutent en interne, puis transmettent l’erreur à une logique de traitement centralisée si elle se produit. - Fonction de callback d’erreur : lors de la création avec
NewRouter, recevoir une fonctionerrCallbacket l’appeler en cas d’erreur afin d’enregistrer les logs de façon centralisée ou d’effectuer un traitement supplémentaire.
- Implémenter un routeur personnalisé (
- Avantages :
- Lorsqu’une erreur survient dans la logique de l’API, un code d’erreur et un message appropriés sont automatiquement renvoyés dans la réponse.
- La gestion des logs est facilitée en enregistrant une fonction de callback permettant d’écrire des logs adaptés à chaque service.
- Réduire la duplication de code et améliorer la maintenabilité.
Envoyer des messages d’erreur clairs (avec RFC7807)
Pour permettre au client de comprendre et de traiter plus clairement les erreurs, il est proposé d’envoyer des messages d’erreur structurés en s’appuyant sur le standard RFC7807.
- Éléments clés de RFC7807 :
type: URI identifiant le type d’erreur (ex. :https://example.com/errors/validation).title: courte description de l’erreur en une ligne.status: identique au code de statut HTTP.detail: description détaillée de l’erreur, lisible par un humain.instance: URI spécifique où l’erreur s’est produite (ex. :/api/users/abc).extensions: objet JSON contenant des informations supplémentaires (ex. :invalid_field,expected_format).
- Implémentation :
-
Créer une structure
RFC7807Erroret y inclure les principaux éléments. -
Générer facilement des objets d’erreur structurés via un modèle de chaînage de méthodes (
WithType(),WithInstance(),WithExtension()). -
Convertir
RFC7807ErrorenHttpErrorvia la méthodeToHttpError()afin de l’intégrer au routeur centralisé. -
Le client peut identifier clairement le type d’erreur, sa cause et l’endroit où elle s’est produite.
-
L’efficacité du développement côté client est améliorée grâce à des réponses API plus cohérentes et plus utiles.
-
5 commentaires
Merci pour cet excellent article.
Merci pour cet excellent article !
À titre d’information, dans Spring, il existe une implémentation dans la bibliothèque
spirng-web>org.springframework.http.ProblemDetail!Merci pour cette bonne introduction !
Après vérification, il a été remplacé par la RFC 9457.
https://datatracker.ietf.org/doc/html/rfc9457
(document 7807 d’origine : https://datatracker.ietf.org/doc/html/rfc7807)
Principales différences entre la RFC 7807 et la RFC 9457
errorspointerPour les nouveaux projets depuis juillet 2023, il est recommandé d’appliquer la RFC 9457
Il semble recommandé de définir le champ
typecomme une URI déréférençable.Pour un service interne, le remplacer par un lien vers la documentation Swagger UI semble également acceptable.