web-dev-qa-db-fra.com

Dois-je utiliser des codes d'état HTTP pour décrire les événements de niveau application

Plusieurs serveurs que j'ai traités renverront HTTP 200 pour les demandes que le client devrait considérer comme un échec, avec quelque chose comme "succès: faux" dans le corps.

Cela ne me semble pas être une implémentation correcte des codes HTTP, en particulier en cas d'échec de l'authentification. J'ai lu les codes d'erreur HTTP résumés assez succinctement: `` 4xx '' indique que la demande ne doit pas être répétée tant qu'elle n'a pas été modifiée, tandis que `` 5xx '' indique que la demande peut ou non être valide et peut être réessayée, mais n'a pas abouti. Dans ce cas, 200: échec de la connexion, ou 200: impossible de trouver ce fichier, ou 200: paramètre x manquant, cela semble définitivement faux.

D'un autre côté, je pouvais voir l'argument avancé selon lequel "4xx" ne devrait indiquer qu'un problème structurel avec la demande. Il convient donc de renvoyer 200: mauvais utilisateur/mot de passe plutôt que 401 non autorisé car le client est autorisé à faire la demande, mais il se trouve que c'est incorrect. Cet argument pourrait être résumé comme suit: si le serveur était en mesure de traiter la demande et de faire une détermination, le code de réponse devrait être 200, et il appartient au client de vérifier le corps pour plus d'informations.

Fondamentalement, cela semble être une question de préférence. Mais ce n'est pas satisfaisant, donc si quelqu'un a une raison pour laquelle l'un ou l'autre de ces paradigmes est plus correct, je voudrais savoir.

56
Kagan Mattson

Question interessante.

Fondamentalement, nous pouvons réduire cela à la bonne façon de classer les choses en termes analogues aux couches OSI. HTTP est généralement défini comme un protocole de niveau application, et HTTP est en effet un protocole client/serveur générique.

Cependant, dans la pratique, le serveur est presque toujours un périphérique de relais, et le client est un navigateur Web, responsable de l'interprétation et du rendu du contenu: le serveur transmet simplement les choses à une application arbitraire, et ces applications renvoient des scripts arbitraires que le navigateur est responsable de l'exécution. L'interaction HTTP elle-même - les formulaires de demande/réponse, les codes d'état, etc. - est principalement une affaire de comment demander, servir et rendre un contenu arbitraire aussi efficacement que possible, sans gêner. De nombreux codes de statut et en-têtes sont en effet conçus à ces fins.

Le problème lorsque vous essayez de superposer le protocole HTTP pour gérer les flux spécifiques à l'application, c'est qu'il vous reste l'une des deux options: 1) Vous devez faire de votre logique de demande/réponse un sous-ensemble des règles HTTP; ou 2) Vous devez réutiliser certaines règles, puis la séparation des préoccupations a tendance à devenir floue. Cela peut sembler agréable et propre au début, mais je pense que c'est l'une de ces décisions de conception que vous finissez par regretter à mesure que votre projet évolue.

Par conséquent, je dirais qu'il vaut mieux être explicite sur la séparation des protocoles. Laissez le serveur HTTP et le navigateur Web faire leur propre chose, et laissez l'application faire sa chose personnelle. L'application doit pouvoir faire des demandes, et elle a besoin des réponses - et sa logique sur la façon de demander, d'interpréter les réponses, peut être plus (ou moins) complexe que la perspective HTTP.

L'autre avantage de cette approche, qui mérite d'être mentionné, est que les applications ne devraient généralement pas dépendre d'un protocole de transport sous-jacent (d'un point de vue logique). HTTP lui-même a changé dans le passé, et maintenant nous avons le coup d'envoi de HTTP 2, après SPDY. Si vous ne voyez votre application que comme un plugin de fonctionnalité HTTP, vous risquez de vous y retrouver lorsque de nouvelles infrastructures prennent le relais.

38
Yam Marcovic

Cette question est un peu basée sur l'opinion, mais de toute façon.

De mon point de vue, 200 peuvent servir à des "erreurs légères". Quand il s'agit de construire des API, j'essaie de faire la distinction entre ces erreurs et les "erreurs graves".

"Soft erreurs" sera servi avec un code d'état de 200, mais contiendra une description d'erreur et un état de réussite de false. Les "erreurs logicielles" ne se produiront que lorsque le résultat est "comme prévu", mais pas un succès au sens strict.

Il est important de noter que les "erreurs logicielles" sont davantage un indice pour l'implémenteur. Il est donc important de fournir également plus d'informations sur l'erreur, comme un message d'erreur lisible par l'homme et/ou une sorte de code qui peut être utilisé pour fournir à l'utilisateur final des commentaires. Ces erreurs fournissent à l'implémenteur (et à l'utilisateur final) plus d'informations sur ce qui s'est passé côté serveur .

Par exemple, disons que vous avez une API avec une fonction de recherche mais pendant une recherche, aucun résultat n'est donné. Ce n'est pas erroné, mais ce n'est pas non plus un "succès", pas au sens strict de la définition.

Exemple formaté en JSON:

{
    "meta" {
        "success": false,
        "message": "Search yielded no results",
        "code": "NORESULTS"
    }
    "data": []
}

"Hard errors" d'autre part, sera servi avec un code d'état qui est recommandé pour l'erreur. L'utilisateur n'est pas connecté? - 403/401. Entrée mal formée? - 400. Erreur de serveur? - 50X. Etc.

Encore une fois, c'est un peu basé sur l'opinion. Certaines personnes veulent traiter toutes les erreurs de la même manière, les "erreurs graves" tout. Aucun résultat trouvé? C'est un 404! De l'autre côté de la médaille, aucun résultat de recherche? - C'est comme prévu, pas d'erreur.

Un autre facteur important à prendre en considération est votre architecture, par exemple; si vous interagissez avec votre API à l'aide de requêtes JavaScript XHR et jQuery ou AngularJS. Ces "erreurs matérielles" devront être traitées avec un rappel séparé, tandis que les "erreurs logicielles" peuvent être traitées avec le rappel "succès". Ne cassant rien, le résultat est toujours "comme prévu". Le code côté client peut alors examiner l'état de réussite et le code (ou message). Et imprimez cela à l'utilisateur final.

24
die maus

Il existe deux aspects d'une API: l'effort de mise en œuvre de l'API et l'effort de tous les clients pour utiliser correctement l'API.

En tant qu'auteur du client, je sais que lorsque j'envoie une demande à un serveur Web, je peux obtenir soit une erreur (jamais correctement adressée au serveur), soit une réponse avec un code d'état. Je dois gérer les erreurs. Je dois gérer une bonne réponse. Je dois gérer les "mauvaises" réponses attendues, documentées. Je dois gérer tout ce qui revient.

Lors de la conception de l'API, vous devez examiner ce qui est le plus facile à traiter pour le client. Si le client envoie une demande bien formée et que vous pouvez faire ce que la demande vous demande de faire, vous devez alors donner une réponse dans la plage 200 (dans certains cas, un nombre différent de 200 dans cette plage est approprié).

Si le client demande "donnez-moi tous les enregistrements comme ...", et qu'il y en a zéro, alors un 200 avec succès et un tableau d'enregistrements zéro est parfaitement approprié. Les cas que vous mentionnez:

"Échec de la connexion" doit généralement être un 401. "Impossible de trouver le fichier" doit être un 404. "Le paramètre x manquant" doit être d'environ 500 (en fait, un 400 si le serveur constate que la demande est incorrecte, et 500 si le serveur est totalement confus par ma demande et n'a aucune idée de ce qui se passe). Renvoyer 200 dans ces cas est inutile. Cela signifie simplement qu'en tant qu'auteur d'un client, je ne peux pas simplement regarder le code de statut, je dois également étudier la réponse. Je ne peux pas simplement dire "statut 200, super, voici les données".

Surtout le "paramètre manquant" - ce n'est pas quelque chose que j'aurais jamais gérer. Cela signifie que ma demande est incorrecte. Si ma demande est incorrecte, je n'ai pas de solution de rechange pour corriger cette demande incorrecte - j'enverrais une demande correcte pour commencer. Maintenant, je suis obligé de le gérer. J'obtiens un 200 et je dois vérifier s'il y a une réponse "paramètre manquant". C'est terrible.

En fin de compte, il existe une douzaine ou deux codes d'état pour gérer de nombreuses situations différentes, et vous devez les utiliser.

16
gnasher729