Je travaille sur un projet et après avoir discuté avec des personnes au travail pendant environ plus d'une heure. J'ai décidé de savoir ce que les gens sur stack-exchange pourraient dire.
Nous écrivons une API pour un système, une requête doit renvoyer une arborescence Organisation ou une arborescence Objectifs.
L'arborescence de l'organisation est l'organisation dans laquelle l'utilisateur est présent. En d'autres termes, cette arborescence doit toujours exister. Dans l'organisation, un arbre de but doit toujours être présent. (c'est là que l'argument a commencé). Au cas où l'arbre n'existerait pas, mon collègue a décidé qu'il serait correct de répondre à l'aide du code d'état 200. Ensuite, j'ai commencé à me demander de corriger mon code car l'application était en train de s'effondrer lorsqu'il n'y avait pas d'arbre.
Je vais essayer d'épargner les flammes et la fureur.
J'ai suggéré de générer une erreur 404 lorsqu'il n'y a pas d'arbre. Cela me permettrait au moins de savoir que quelque chose ne va pas. Lorsque j'utilise 200, je dois ajouter une vérification spéciale à ma réponse dans le rappel de réussite pour gérer les erreurs. Je m'attends à recevoir un objet, mais je peux recevoir une réponse vide car rien n'est trouvé. Cela semble tout à fait juste de marquer la réponse comme un 404. Et puis la guerre a commencé et j'ai reçu le message que je ne comprenais pas le schéma de code de statut HTTP. Donc, je suis ici et demande ce qui ne va pas avec 404 dans ce cas? J'ai même eu l'argument "Il n'a rien trouvé , il est donc correct de retourner 200". Je crois que c'est faux car l'arbre devrait toujours être présent. Si nous ne trouvons rien et que nous attendons quelque chose, ce devrait être un 404.
Plus d'informations,
J'ai oublié d'ajouter les URL récupérées.
Les organisations
/OrgTree/Get
Buts
/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...
Mon erreur, les deux paramètres sont nécessaires. Si une versionDate pouvant être analysée avec une date est fournie, la révision se ferme. Si vous entrez quelque chose dans le passé, la première révision sera renvoyée. Si par Id avec un identifiant qui n'existe pas, je soupçonne qu'il va retourner une réponse vide avec 200.
Supplémentaire
De plus, je pense que la meilleure solution au problème consiste à créer des objets par défaut lors de la création d'organisations. Ne pas avoir d'arborescence ne devrait pas être un cas valable et devrait être considéré comme un comportement indéfini. Il est impossible qu'un compte puisse être utilisé sans les deux arbres. Pour cette raison, ils devraient toujours être présents.
aussi je me suis lié ceci (un semblable mais je ne peux pas le trouver)
http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png
la source
/GoalTree/GetById?versionId=CompletelyInvalidID
revenir? Pas de succès, car la ressource nommée/GoalTree/GetById?versionId=CompletelyInvalidID
était littéralement introuvable.Réponses:
En cas de doute, consultez la documentation . L'examen des définitions du W3C pour les codes d'état HTTP nous donne ceci:
Dans le contexte de votre API, cela dépend beaucoup de la manière dont les requêtes sont créées et de la manière dont les objets sont récupérés. Mais, mon interprétation a toujours été que:
200
code, s'il n'existe pas, renvoyer le404
code correct .200
code. La raison en est que la requête était valide, qu'elle a réussi et que la requête n'a rien renvoyé.Donc, dans ce cas, vous avez raison , le service ne recherche pas "une chose spécifique" mais demande une chose particulière, si cette chose ne se trouve pas, dites-le clairement.
Je pense que Wikipedia le dit le mieux:
Cela me semble assez clair.
Concernant les exemples de demandes
Pour le format, vous avez dit, vous renvoyez toujours la révision la plus proche à cette date. Il ne retournera jamais un objet, il devrait donc toujours y retourner
200 OK
. Même si cela pouvait prendre une plage de dates et que la logique devait renvoyer tous les objets dans cette période, 200 OK - 0 Results est correct, car c'est ce à quoi la demande était destinée - l'ensemble des éléments répondant à ce critère.Cependant, ce dernier est différent car vous demandez un objet spécifique , probablement unique, avec cette identité. Retourner
200 OK
dans ce cas est faux car la ressource demandée n'existe pas et n'est pas trouvée .Concernant le choix des codes de statut
Vous avez mentionné dans un commentaire utilisant un code 5xx, mais votre système fonctionne. Il a été demandé à une requête qui ne fonctionne pas et doit communiquer cela à l'agent utilisateur. Peu importe comment vous le découpez, il s'agit d'un territoire 4xx.
Considérons un extraterrestre qui interroge notre système solaire
la source
Ignorant le fait que / GoalTree / Get * ressemble à un verbe et non à des ressources, vous devez toujours renvoyer 200, car l'URI / GoalTree / Get * représente des ressources toujours disponibles pour l'accès et ne constitue pas une erreur du client s'il n'y a pas d'arbre résultant. une requête. Il suffit de retourner 200 avec un ensemble vide lorsqu'il n'y a aucune entité à renvoyer.
Vous utilisez 404 si la ressource n'est pas trouvée, pas lorsqu'il n'y a pas d'entité.
En d'autres termes, si vous voulez renvoyer 404 pour vos objets, donnez-leur leurs propres URI.
la source
/GoalTree/GetById?versionId=12345
est un URI tout à fait correct (enfin, relatif, au moins) qui identifie une ressource spécifique, à savoir les données correspondant à l'ID de version12345
dans le système. Si aucune donnée avec un tel ID n'existe, une réponse HTTP 404 est parfaitement appropriée. Bien entendu, le corps de la réponse doit, dans tous les cas, contenir une réponse formatée de manière appropriée (par exemple, JSON, si c'est ce à quoi s'attendent les clients types demandant de telles ressources) indiquant la nature spécifique et la cause de l'erreur.C'est une question intéressante, car il s'agit de la spécification du système.
La réponse de imel96 m'a convaincu qu'une réponse 404 ne serait pas une réponse correcte, car la famille de codes 4xx est principalement destinée aux erreurs utilisateur / client , et ce n'est pas le cas. L'URL est bien formée et l'arbre doit être là; si ce n'est pas le cas, le système est dans un état incohérent!
Il s’agit donc d’une erreur de serveur , c’est-à-dire quelque chose de la famille 5xx. Peut-être une erreur de serveur interne 500 générique ou un service 503 indisponible (le service étant "récupérez-moi l'arborescence qui doit y figurer").
la source
Je dirais qu'un code de réponse 200 ou 404 peut être valide , selon votre perception de la situation.
Le fait est que les codes de réponse HTTP sont définis dans le contexte d'un serveur , qui peut fournir diverses ressources en fonction de leur URL. Dans ce contexte, les significations de
200 OK
et404 Not Found
sont parfaitement claires: le premier indique "voici la ressource que vous avez demandée", tandis que le dernier indique "désolé, je n'ai aucune ressource de ce type".Toutefois, dans votre cas, vous disposez d'une couche d' application supplémentaire entre le serveur HTTP et les ressources réelles (arborescences) demandées. L'application occupe une sorte d'espace intermédiaire qui n'est pas bien traité dans la spécification HTTP.
Du point de vue de serveur Web, l'application ressemble genre de comme une ressource: il est généralement un fichier sur le serveur, identifié par (une partie de) l'URL, comme les autres ressources (par exemple , les fichiers statiques) , le serveur peut servir. D'autre part, c'est une sorte de ressource étrange, car elle consiste en un code exécutable qui détermine de manière dynamique le contenu, voire même le code d'état, de la réponse, ce qui la fait ressembler à certains égards à un mini-serveur.
En particulier, dans votre exemple, le serveur Web peut très bien localiser l’application, mais l’application ne parvient pas à localiser la sous-ressource (arborescence) demandée. Maintenant, si vous considérez que l'application est simplement une extension du serveur et que le sous-élément (l'arborescence) est la ressource réelle, une réponse 404 est appropriée: le serveur a simplement délégué la tâche de recherche de la ressource réelle à l'application. , ce qu’il a échoué à son tour.
D'autre part, si votre point de vue est que l'application est la ressource demandée, il est évident que le serveur Web doit renvoyer une réponse 200 ; après tout, l'application a été trouvée et exécutée correctement. Évidemment, dans ce cas, l’application doit en réalité renvoyer un corps de réponse valide au format attendu, indiquant (en utilisant le protocole de niveau supérieur que le format encode) qu'aucune donnée réelle correspondant à la requête n'a été trouvée.
Ces deux points de vue peuvent avoir un sens. Dans la plupart des cas , du moins pour les applications destinées à être directement accessibles via HTTP avec un navigateur Web ordinaire, je préférerais la vue précédente : l'utilisateur ne se soucie généralement pas des détails internes, tels que la différence entre le serveur et l'application, se soucient de savoir si les données qu'ils voulaient est là ou non.
Toutefois, dans le cas spécifique d’une application conçue pour communiquer avec d’autres programmes informatiques à l’aide d’un protocole d’API de haut niveau personnalisé, en utilisant HTTP uniquement comme couche de transport de bas niveau , un argument doit être avancé en faveur de cette dernière vue : Les clients qui interagissent avec une telle application ne se préoccupent vraiment pas, au niveau HTTP , de savoir s'ils ont réussi à contacter l'application ou non. Tout le reste est, dans de tels cas, souvent plus naturellement communiqué en utilisant le protocole de niveau supérieur.
Dans tous les cas, quels que soient les points de vue ci-dessus que vous préférez, vous devez garder à l’esprit quelques détails. La première est que, dans de nombreux cas, il peut exister une distinction significative entre une ressource (essentiellement) vide et une ressource inexistante .
Au niveau HTTP, une ressource vide serait simplement indiquée par un code de réponse 200 et un corps de réponse vide, tandis qu'une ressource inexistante serait indiquée par une réponse 404 et un corps de ressource expliquant l'absence de la ressource. Dans un protocole API de niveau supérieur, on indiquera généralement une ressource non existante par une réponse d'erreur, contenant un code / message d'erreur spécifique au protocole, tandis qu'une réponse vide serait simplement une structure de réponse normale sans éléments de données.
(Notez qu'une ressource n'a pas besoin d'être littéralement zéro octet pour être "vide" dans le sens que je veux dire plus haut. Par exemple, un résultat de recherche sans éléments correspondants est considéré comme vide au sens large, de même qu'un résultat de requête SQL avec pas de lignes ou un document XML ne contenant aucune donnée réelle.)
En outre, bien sûr, si l'application ne croit vraiment que la sous - ressource demandée doit être là, mais ne peut pas le trouver, puis un troisième code de réponse possible existe:
500 Internal Server Error
. Une telle réponse a du sens si l’existence de la ressource est une condition préalable supposée de l’application, de sorte que son absence indique nécessairement un dysfonctionnement interne.Enfin, vous devez toujours garder à l'esprit la loi de Postel :
Que le serveur doit répondre dans une situation particulière avec une 200 ou une réponse 404, qui n'excuse pas vous en tant que client implementor de manipulation soit une réponse appropriée et de la manière qui maximise l' interopérabilité robuste. Bien sûr, on peut discuter de ce que signifie une manipulation "appropriée" dans différentes situations, mais cela ne devrait certainement pas inclure normalement un crash ou une "chute".
la source
Que diriez-vous d'un 204 sans contenu? Cela suggérerait que votre demande a été traitée avec succès mais ne renvoie rien. C'est toujours un "succès" mais vous permet de voir si vous avez des résultats basés uniquement sur le code d'état.
la source
Si l'URL représente une ressource qui n'a jamais existé, renvoyer 404 Introuvable
Si l'URL représente une ressource qui est une liste vide, retournez une liste vide et 200 OK.
Exemple:
Si l'URL représente une ressource qui existait auparavant, renvoyer 410 Gone.
En ce qui concerne le dialogue de Lego Stormtrooper:
la source
D'après le son, il s'agit d'une API à usage interne . Cela donne l'avantage d'utiliser le schéma qui offre le plus d' avantages , qu'il soit manuel ou non (spécification). Cela ne signifie pas complètement inventer vos propres codes de statut, mais il est correct de "plier" les règles un peu si elles sont bénéfiques.
Je suis d’accord avec votre position selon laquelle vous devriez obtenir un code d’état indiquant que quelque chose a mal tourné. C'est après tout ce que les codes d'état sont pour. Vous bénéficiez également des bibliothèques qui génèrent des exceptions / etc. sur le code d’état non-200 afin que vous n’ayez pas à vérifier explicitement (ou vous pouvez écrire votre propre wrapper qui le fait).
Je suis également d'accord avec le point de vue d'Andres F. selon lequel 500 est approprié puisque l'arbre devrait exister. Dans la pratique, j’aime séparer les erreurs de serveur en deux catégories. Quelque chose d' inattendu s'est mal passé et de quelque chose que je peux pratiquement vérifier. Cela se traduit par les codes d'état suivants,
Dans votre cas particulier, vous pouvez vérifier si l’arborescence existe ou non côté serveur et si elle n’y existe pas, renvoyer un 409. C’est une erreur attendue (vous savez que cela peut arriver, vous pouvez le vérifier, etc.) . 409 conflit est juste ma préférence personnelle, un 5xx peut également être approprié tant que vous pouvez vous asseoir et décider avec votre équipe.
La catégorisation de tels codes vous aide à identifier plus rapidement le type d'erreur, mais elle peut avoir des avantages dépassant l'organisation. Souvent, avec des erreurs de site Web, vous ne voulez pas que le client reçoive des erreurs inattendues, car cela peut poser un problème de sécurité et révéler des vulnérabilités. Vous renvoyez donc 500 "Une erreur s'est produite". et enregistrez l'erreur complète sur le serveur. Mais si une erreur attendue se produit en tant que 409, vous savez qu'il serait prudent de la montrer au client et vous ne serez pas obligé de les laisser dans l'ignorance de ce qui s'est passé. C’est une utilisation pratique que je peux raconter, mais il y a beaucoup de possibilités.
C'est un peu un accroc parce que vous postez ceci parce que vous ne pouvez pas être d'accord avec vos collègues, mais il semblerait que vous discutiez davantage de la sémantique et de ce qui est politiquement correct. Peu importe qui est le plus approprié, tant que vous pouvez créer un système qui profite le plus à l'entreprise.
Par contre, s’il s’agissait d’une API publique respectant les spécifications au plus près, ce serait plus important pour éviter toute confusion au sein de la communauté.
la source
Tentative tangentielle: Si un utilisateur utilise finalement l’API (via une interface graphique), je vous conseillerais de faire tout ce qui facilite la vie de l’utilisateur final. La non-existence de l’arbre au moment où il devrait exister est une erreur "Incohérence du modèle de domaine". Une erreur système survient lorsque vous manquez de mémoire ou avez eu une autre défaillance système. Donc, retourner 5xx est inapproprié. Comme mentionné par plusieurs personnes ci-dessus, 4xx pourrait être approprié si l'arbre lui-même avait son propre URI, ce qui n'est pas le cas ici. Mais voici ce que 404 dit au client: vous pouvez essayer encore et encore jusqu'à ce que vous obteniez quelque chose en retour. Si vous avez renvoyé 200, vous pouvez renvoyer un nombre suffisant de diagnostics à l'utilisateur ou à l'agent d'utilisateur afin que celui-ci puisse afficher un message afin que l'utilisateur cesse de réessayer et contacte uniquement le support. D'autre part, si cette API est destinée uniquement aux systèmes,
la source