web-dev-qa-db-fra.com

REST Une erreur d'API renvoie de bonnes pratiques

Je recherche des conseils sur les bonnes pratiques en matière de renvoi des erreurs d'une API REST. Je travaille sur une nouvelle API pour pouvoir la suivre dans n'importe quelle direction. 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, par exemple, un client tente d'ajouter une nouvelle ressource mais 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 adresses URI de requête douteuses). J'ai examiné les codes d'erreur HTTP bénis, mais aucun élément de la plage 400-417 ne semble correct de signaler des erreurs spécifiques à une application. Alors au début, j’étais tenté de renvoyer mon erreur d’application avec 200 OK et une charge XML spécifique (c.-à-d. Payez-nous plus et vous obtiendrez le stockage dont vous avez besoin!), Mais j’ai arrêté de penser à cela et cela semble savonneux (/ haussement d'épaules d'horreur). En outre, j'ai l'impression de fractionner les réponses d'erreur en plusieurs cas distincts, car certains dépendent du code de statut http et d'autres du contenu.

Alors, quelles sont les recommandations de l'industrie? Les bonnes pratiques (veuillez expliquer pourquoi!) Et quel type de gestion des erreurs dans l'API REST simplifie la vie du code client?

608
Remus Rusanu

Alors au début, j’étais tenté de renvoyer mon erreur d’application avec 200 OK et une charge XML spécifique (c.-à-d. Payez-nous plus et vous obtiendrez le stockage dont vous avez besoin!), Mais j’ai arrêté de penser à cela et cela semble savonneux (/ haussement d'épaules d'horreur).

Je ne retournerais pas un 200 à moins qu'il n'y ait vraiment rien qui cloche dans la demande. De RFC2616 , 200 signifie "la requête a abouti".

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

Le serveur a compris la demande, mais refuse de l'exécuter. L'autorisation n'aidera pas et la demande NE DEVRAIT PAS être répétée. Si la méthode de la demande n'était pas HEAD et que le serveur souhaite rendre publique la raison pour laquelle la demande n'a pas été remplie, il DEVRAIT décrire le motif du refus dans l'entité. Si le serveur ne souhaite pas mettre ces informations à la disposition du client, le code d'état 404 (non trouvé) peut être utilisé à la place.

Cela indique au client que la demande était OK, mais qu'elle a échoué (quelque chose qu'un 200 ne fait pas). 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 à l'esprit?

215
Rich Apodaca

Une excellente ressource pour choisir le code d'erreur HTTP correct pour votre API: http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

Un extrait de l'article:

Où commencer:

enter image description here

2XX/3XX:

enter image description here

4XX:

enter image description here

5XX:

enter image description here

547
Omar Ali

Le choix principal est de savoir si vous souhaitez ou non traiter le code de statut HTTP dans le cadre de votre API REST.

Les deux manières fonctionnent bien. Je conviens que, à proprement parler, une des idées de REST est que vous devez utiliser le code d'état HTTP dans le cadre de votre API (renvoyer 200 ou 201 pour une opération réussie et un 4xx ou 5xx selon divers cas d’erreur.) Cependant, il n’existe pas de REST police. Tu peux faire ce que tu veux. J'ai vu des API beaucoup plus flagrantes non-REST appelées "RESTful".

À 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 l'ensemble des réponses non-200 que par le passé.

Le code d'état HTTP fait partie de votre api

  1. Vous devrez choisir avec soin les codes 4xx qui correspondent à vos conditions d'erreur. Vous pouvez inclure un message reste, XML ou en texte brut comme charge utile comprenant un sous-code et un commentaire descriptif.

  2. Les clients devront utiliser une structure logicielle leur permettant d’obtenir le code de statut de niveau HTTP. Habituellement faisable, 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, puis a répondu (cas de réussite et d'erreur)

  2. TOUTES vos réponses devraient inclure des informations "enveloppe" ou "en-tête". Typiquement quelque chose comme:

    envelope_ver: 1.0 
     status: # utilisez les codes de votre choix. Réservez un code pour réussir. 
     msg: "ok" # Chaîne humaine qui reflète le code. Utile pour le débogage. 
     Data: ... # Les données de la réponse, le cas échéant.
  3. Cette méthode peut être plus facile pour les clients car le statut de la réponse est toujours au même endroit (aucun sous-code n'est nécessaire), aucune limite sur les codes, pas besoin d'extraire le code de statut de niveau HTTP.

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

Problèmes principaux:

  1. Assurez-vous d'inclure les numéros de version afin de pouvoir modifier ultérieurement la sémantique de l'API si nécessaire.

  2. Document...

87
Larry K

N'oubliez pas qu'il existe plus de codes d'état que ceux définis dans les RFC HTTP/1.1. Le registre IANA est situé à l'emplacement http://www.iana.org/assignments/http-status-codes . Dans le cas où vous avez mentionné le code d'état 507, cela sonne bien.

40
Julian Reschke

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

Rappelez-vous que les erreurs 5xx sont côté serveur, autrement dit le client ne peut rien changer à sa demande pour faire passer la demande. Si le quota du client est dépassé, il ne s'agit certainement pas d'une erreur de serveur. Il convient donc d'éviter 5xx.

22
SerialSeb

Je sais que la soirée a pris beaucoup de retard, mais en 2013, nous avons quelques types de supports permettant de couvrir le traitement des erreurs de manière commune (RESTful). Voir "vnd.error", application/vnd.error + json ( https://github.com/blongden/vnd.error ) et "Détails du problème pour les API HTTP", application/problem + json ( https://tools.ietf.org/html/draft-nottingham-http-problem-05 ).

19
Jørn Wildt

Il y a deux sortes d'erreurs. Erreurs d'application et erreurs HTTP. Les erreurs HTTP consistent uniquement à informer votre gestionnaire AJAX que les choses se sont bien passées et qu'il ne faut en aucun cas les utiliser.

5xx Erreur de serveur

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates (RFC 2295 )
507 Insufficient Storage (WebDAV) (RFC 4918 )
509 Bandwidth Limit Exceeded (Apache bw/limited extension)
510 Not Extended (RFC 2774 )

2xx succès

200 OK
201 Created
202 Accepted
203 Non-Authoritative Information (since HTTP/1.1)
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status (WebDAV)

Cependant, la manière dont vous concevez vos erreurs d’application dépend vraiment de vous. Stack Overflow, par exemple, envoie un objet avec les propriétés response, data et message. Je crois que la réponse contient true ou false pour indiquer si l'opération a réussi (généralement pour les opérations d'écriture). Les données contiennent la charge utile (généralement pour les opérations de lecture) et le message contient des métadonnées supplémentaires ou des messages utiles (tels que des messages d'erreur lorsque response est false).

18
aleemb

D'accord. La philosophie de base de REST consiste à utiliser l'infrastructure Web. Les codes d'état HTTP sont la structure de messagerie qui permet aux parties de communiquer entre elles sans augmenter la charge utile HTTP. Ce sont déjà des codes universels établis établissant le statut de réponse. Par conséquent, pour être véritablement RESTful, les applications doivent utiliser ce cadre pour communiquer le statut de la réponse.

L'envoi d'une réponse d'erreur dans une enveloppe HTTP 200 est trompeur et oblige le client (consommateur d'api) à analyser le message, le plus souvent de manière non standard ou exclusive. Cela n’est pas non plus efficace: vous obligerez vos clients à analyser chaque fois la charge HTTP pour comprendre le statut de la réponse "réelle". Cela augmente le traitement, ajoute de la latence et crée un environnement dans lequel le client peut faire des erreurs.

9
Kingz

Modéliser votre API sur les "meilleures pratiques" existantes pourrait être la voie à suivre. Par exemple, voici comment Twitter gère les codes d’erreur https://developer.Twitter.com/en/docs/basics/response-codes

6
Gokul

Veuillez vous en tenir à la sémantique du protocole. Utilisez 2xx pour les réponses réussies et 4xx, 5xx pour les réponses d'erreur - que ce soit vos exceptions métier ou autre. Si l'utilisation de 2xx pour une réponse quelconque avait été le cas d'utilisation prévu dans le protocole, ils n'auraient pas d'autre code d'état en premier lieu.

5
rahil008

N'oubliez pas les erreurs 5xx pour les erreurs d'application.

Dans ce cas, qu'en est-il de 409 (Conflict)? Cela suppose que l'utilisateur peut résoudre le problème en supprimant les ressources stockées.

Sinon, 507 (pas tout à fait standard) peut également fonctionner. Je ne voudrais pas utiliser 200, sauf si vous utilisez 200 pour les erreurs en général.

3
Kathy Van Stone