634 votes

Bonnes pratiques en matière de retour d'erreur des API REST

Je suis à la recherche de conseils sur les bonnes pratiques en matière de retour d'erreurs à partir d'une API REST. Je travaille sur une nouvelle API et je peux donc la prendre dans n'importe quelle direction pour le moment. Mon type de contenu est XML pour le moment, mais je prévois de prendre en charge JSON à l'avenir.

J'ajoute maintenant quelques cas d'erreur, comme par exemple un client qui tente d'ajouter une nouvelle ressource mais qui a dépassé son quota de stockage. Je traite déjà certains cas d'erreur avec des codes d'état HTTP (401 pour l'authentification, 403 pour l'autorisation et 404 pour les mauvaises URI de demande). J'ai examiné les codes d'erreur HTTP bénis, mais aucun de la gamme 400-417 ne semble convenir pour signaler des erreurs spécifiques à une application. Au début, j'ai été tenté de renvoyer mon erreur d'application avec 200 OK et une charge utile XML spécifique (par exemple : "Payez-nous plus et vous aurez le stockage dont vous avez besoin !") mais je me suis arrêté pour y réfléchir et cela semble trop savonneux (/ haussement d'épaules d'horreur). De plus, j'ai l'impression de diviser les réponses aux erreurs en plusieurs cas distincts, car certaines sont liées au code d'état http et d'autres au contenu.

Quelles sont les recommandations de l'industrie ? Les bonnes pratiques (expliquez pourquoi !) et aussi, du point de vue du client, quel type de traitement des erreurs dans l'API REST facilite la vie du code client ?

7 votes

Pour clarifier : je ne suis pas tant intéressé par le code d'état HTTP particulier à renvoyer, mais plutôt par la question de savoir si une bonne pratique REST consiste à combiner les erreurs de charge utile avec les codes d'état HTTP ou s'il est préférable de se fier uniquement à la charge utile.

3 votes

Le manuel de conception d'API REST couvre très bien ce sujet.

13 votes

La question ne demande pas une opinion, mais des conseils/recommandations et devrait être rouverte et utilisée comme référence. Quel était l'intérêt de fermer en 2016 la question, qui a été créée en 2009, a plus de 400 votes et aucune réponse existante basée sur des opinions.

230voto

Rich Apodaca Points 7327

Au début, j'étais tenté de renvoyer l'erreur de mon application avec 200 OK et une charge utile XML spécifique (c'est-à-dire : "Payez-nous plus et vous obtiendrez le stockage dont vous avez besoin !") mais je me suis arrêté pour y réfléchir et cela semble trop savonneux (/ haussement d'épaules d'horreur).

Je ne renverrais pas un 200 à moins qu'il n'y ait vraiment rien d'anormal dans la demande. À partir de RFC2616 200 signifie "la requête a réussi".

Si le quota de stockage du client a été dépassé (pour une raison quelconque), je renvoie un message 403 (interdit) :

Le serveur a compris la demande, mais refuse de l'exécuter. L'autorisation ne sera pas utile et la demande NE DEVRAIT PAS être répétée. Si la méthode de requête n'était pas HEAD et que le serveur souhaite rendre publique la raison pour laquelle la requête n'a pas été satisfaite, il DEVRAIT décrire la raison du refus dans l'entité. Si le serveur ne souhaite pas mettre cette information à la disposition du client, le code d'état 404 (Not Found) peut être utilisé à la place.

Cela indique au client que la demande était correcte, mais qu'elle a échoué (ce que ne fait pas un 200). Cela vous donne également l'occasion d'expliquer le problème (et sa solution) dans le corps de la réponse.

Quelles autres conditions d'erreur spécifiques aviez-vous en tête ?

6 votes

Dois-je inclure mon message d'erreur détaillé dans le corps du message, c'est-à-dire une paire code XML/chaîne de caractères ? Comment les clients gèrent-ils au mieux cette situation ? Par exemple, je sais que les clients basés sur C# WebRequest renvoient "Bad Request" ou "Forbidden" et ne donnent pas le corps de la réponse.

18 votes

Le corps d'un message 403 "devrait" contenir les détails de l'erreur. Que le client soit prêt à utiliser ces informations est une autre histoire. Il est plus logique que ce format soit le même que celui de toutes les autres charges utiles (par exemple, XML, JSON).

1 votes

... et si les détails ne sont pas renvoyés dans le 403, un 404 "peut" être utilisé à la place (cela ne me semble pas être la meilleure option, cependant).

87voto

Larry K Points 16266

Le choix principal est de savoir si vous voulez traiter le code d'état HTTP comme faisant partie de votre API REST ou non.

Les deux méthodes fonctionnent bien. Je suis d'accord sur le fait que, strictement parlant, l'une des idées de REST est que vous devez utiliser le code d'état HTTP comme partie intégrante de votre API (renvoyer 200 ou 201 pour une opération réussie et un 4xx ou 5xx selon les différents cas d'erreur). Cependant, il n'y a pas de police REST. Vous pouvez faire ce que vous voulez. J'ai vu des API non REST bien plus flagrantes être qualifiées de "RESTful".

A ce stade (Août 2015) Je vous recommande d'utiliser le code d'état HTTP dans le cadre de votre API. Il est maintenant beaucoup plus facile de voir le code de retour lors de l'utilisation de frameworks que par le passé. En particulier, il est maintenant plus facile de voir le cas de retour non-200 et le corps des réponses non-200 que par le passé.

Le code d'état HTTP fait partie de votre API.

  1. Vous devrez choisir soigneusement les codes 4xx qui correspondent à vos conditions d'erreur. Vous pouvez inclure un message rest, xml ou en texte clair comme charge utile qui comprend un sous-code et un commentaire descriptif.

  2. Les clients devront utiliser un cadre logiciel qui leur permettra d'obtenir le code d'état au niveau HTTP. C'est généralement faisable, mais pas toujours simple.

  3. Les clients devront faire la distinction entre les codes d'état HTTP qui indiquent une erreur de communication et vos propres codes d'état qui indiquent un problème au niveau de l'application.

Le code d'état HTTP ne fait PAS partie de votre API.

  1. Le code d'état HTTP sera toujours 200 si votre application a reçu la demande et y a répondu (en cas de succès ou d'erreur).

  2. TOUTES vos réponses doivent comporter des informations sur l'"enveloppe" ou l'"en-tête". Typiquement quelque chose comme :

    envelope\_ver: 1.0
    status:  # use any codes you like. Reserve a code for success. 
    msg: "ok" # A human string that reflects the code. Useful for debugging.
    data: ...  # The data of the response, if any.
  3. Cette méthode peut être plus facile pour les clients puisque le statut de la réponse est toujours au même endroit (pas de sous-codes nécessaires), pas de limites sur les codes, pas besoin de récupérer le code de statut au niveau HTTP.

Voici un post avec une idée similaire : http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

Principales questions :

  1. Veillez à inclure les numéros de version afin de pouvoir modifier ultérieurement la sémantique de l'api si nécessaire.

  2. Document...

8 votes

Ty. L'option 2 ressemble à du SOAP dans des vêtements de repos cependant...

138 votes

Non, tout faire passer par un tunnel de 200 n'est pas du tout reposant. Cela empêche les intermédiaires de comprendre le résultat d'une opération, ce qui tue toute forme de mise en cache, cela cache la sémantique de l'opération, et cela impose de comprendre le contenu du message pour traiter une erreur, violant ainsi la contrainte des messages autonomes.

13 votes

Renvoyer les détails de l'erreur avec un 200 n'est peut-être pas RESTful, mais c'est tout de même une réponse utile (si vous ignorez la remarque "Both ways are restful")... Le point le plus important est peut-être qu'une API RESTful n'est peut-être pas la meilleure option pour le PO.

40voto

Julian Reschke Points 12698

N'oubliez pas qu'il existe plus de codes d'état que ceux définis dans les RFC HTTP/1.1, le registre IANA se trouve à l'adresse suivante http://www.iana.org/assignments/http-status-codes . Pour le cas que vous avez mentionné, le code d'état 507 semble correct.

3 votes

Hmm, alors qu'à première vue "507 Insufficient Storage" semble être approprié, je serais réticent à l'utiliser puisqu'il est prévu comme une extension WebDAV (assez spécifique) et non une exception générale "hey you're out of space". Néanmoins, je suppose que vous pourriez l'utiliser.

1 votes

Non, ce n'est pas du tout spécifique à WebDAV. Il y a une raison pour laquelle il y a un registre pour les codes d'état HTTP.

1 votes

507 ne fait même pas partie de HTTP 1.1 ; c'est une partie de RFC4918, intitulée "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)".

22voto

serialseb Points 5509

Comme d'autres l'ont souligné, il est parfaitement possible d'avoir une entité de réponse dans un code d'erreur.

N'oubliez pas que les erreurs 5xx sont liées au serveur, c'est-à-dire que le client ne peut rien changer à sa demande pour que celle-ci soit acceptée. Si le quota du client est dépassé, il ne s'agit certainement pas d'une erreur du serveur, et les erreurs 5xx sont donc à éviter.

0 votes

Je ne suis pas d'accord. Quota Exceeded serait une erreur de serveur (5xx) car : La demande du client est valide et aurait abouti si le quota avait été respecté, ce qui exclut la série 400.

4 votes

Mais le serveur n'a rien fait de mal.

12voto

user2966445 Points 54

Tous les grands acteurs utilisant des API REST avec lesquels j'ai travaillé (Vimeo, Facebook, Twitter) renvoient des codes d'état 200 pour chaque requête, et je suis d'accord avec leur approche.

Le code d'état 200 signifie que la demande elle-même a abouti sans erreur (l'acte d'accéder à l'API et de renvoyer un résultat).

Dans le cadre d'un appel spécifique, une erreur peut se produire, et c'est là qu'un code d'erreur spécifique peut être renvoyé.

J'utilise une classe personnalisée appelée APIResult et reviennent toujours :

  • Statut - OK ou Fail
  • Data (facultatif) - Toute donnée renvoyée
  • Error Code (facultatif) - Code HTTP associé à l'erreur.
  • Message d'erreur (facultatif) - Message associé à l'erreur
  • Error Explanation (facultatif) - Informations supplémentaires sur l'erreur.

Je pense que cela est très similaire à la façon dont les résultats de l'API de Vimeo sont structurés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X