Code d'état HTTP pour une requête partiellement réussie

115

J'ai une application qui envoie des messages aux utilisateurs. Dans une demande de publication, une chaîne XML est transférée qui comprend tous les utilisateurs qui devraient recevoir ce message particulier. Si l'un des utilisateurs de la liste n'existe pas, je renvoie la liste des utilisateurs manquants au client pour une évaluation plus approfondie.

Maintenant, je me demande quel serait le code de statut approprié pour l'application en disant que la demande a été acceptée mais qu'il y avait des choses qui ne pouvaient pas être faites.

Le problème serait évité s'il n'était pas autorisé à inclure les utilisateurs manquants dans la liste. Ensuite, la tentative d'envoi obtiendrait simplement une erreur 4xx. Mais il ne sert à rien de former l'API de cette façon. D'un autre côté, je pourrais considérer que la condition d'erreur est purement spécifique à l'application. Mais envoyer un 200 ne semble pas juste. Et ce serait bien de donner au client un indice pour examiner en profondeur la réponse d'erreur. par exemple pour éviter d'envoyer des messages à ces utilisateurs encore et encore

Norbert Hartl
la source

Réponses:

66

J'ai traité un problème très similaire. Dans ce cas, j'ai renvoyé un

207 multi-états

Maintenant, ce n'est pas du HTTP strict, cela fait partie de l'extension WebDAV, donc si vous n'avez pas de contrôle sur le client, alors ce n'est pas bon pour vous. Si vous le faites, vous pouvez faire quelque chose comme ceci:

   <?xml version="1.0" encoding="utf-8" ?>
   <D:multistatus xmlns:D='DAV:'>
     <D:response>
       <D:user>user-123</D:user>
       <D:status>success</D:status>
     </D:response>
     <D:response>
       <D:user>user-789</D:user>
       <D:status>failure</D:status>
     </D:response>
   </D:multistatus>

Mais encore une fois, il s'agit d'une extension HTTP et vous devez également contrôler le client.

Kylar
la source
3
J'ai pensé à l'utiliser mais je n'étais pas tout à fait à l'aise avec. Merci!
Norbert Hartl
La bonne chose à ce sujet est que vous pouvez renvoyer autant ou peu de données pertinentes que vous le souhaitez - ce qui est particulièrement utile pour les ensembles de données mixtes, c'est-à-dire où certaines échouent et d'autres réussissent.
Kylar
Je comprends. J'essaie simplement d'éviter un niveau supplémentaire de gestion du statut (ce qui n'est pas sympa à mon humble avis). La plupart de mon code fonctionne avec ceux HTTP. Et je pense que mon cas d'utilisation décrit se passera bien sans.
Norbert Hartl
Vous pouvez toujours renvoyer un corps - envoyez un 200 avec une réponse JSON ou tout ce que vous voulez pour déterminer lesquels ont réussi.
Kylar
Oui je sais. Mais si vous renvoyez un corps, vous devez l'analyser. Et à ce moment-là, vous introduisez une deuxième couche de gestion de la logique d'application. Cela augmente la complexité et vous avez besoin d'une bonne raison de le faire alors.
Norbert Hartl
65

J'ai eu le même problème et j'ai fini par utiliser deux solutions différentes:

  • Code de retour HTTP 202: Accepted, indiquant que la requête était correcte, mais il n'y a aucune garantie que tout s'est réellement passé comme il se doit.
  • Renvoyez une normale 200dans la réponse, mais incluez une liste de ce qui ne s'est pas déroulé dans le corps de la réponse.

Le second fonctionne généralement mieux, mais le premier est idéal si vous êtes paresseux ou utilisez une file d'attente pour le traitement.

Arne
la source
5
202 ne fait-il pas plus référence à quelque chose comme la file d'attente?
Sinaesthetic
6
Oui, @Sinaesthetic. D'après la spécification HTTP 1.1 la plus récente, "(...) la demande a été acceptée pour le traitement, mais le traitement n'est pas terminé". Donc, pour un succès partiel, 202 n'est pas approprié.
Huercio le
-4

Qu'en est-il de l'utilisation du 206 Contenu partiel. Je sais que 206 concerne davantage les plages, mais que se passe-t-il s'il peut indiquer une demande partiellement réussie?

Yusuf
la source
MDN déclare comme suit: "Le code de réponse d'état de réussite du contenu partiel HTTP 206 indique que la demande a réussi et que le corps contient les plages de données demandées, comme décrit dans l'en-tête Range de la demande." Pour autant que je sache, 206 Contenu Partiel est strictement pour les demandes avec une gamme de contenu.
sbbs
-14

Le protocole de transfert HyperText traite du côté transmission des choses. Il n'a pas de codes d'erreur pour traiter les erreurs au niveau de l'application.

Retourner 200 est la bonne chose à faire ici. En ce qui concerne HTTP, la demande a été reçue correctement, traitée correctement et vous renvoyez la réponse. Donc, au niveau HTTP, tout va bien. Toutes les erreurs ou avertissements liés à l'application exécutée sur http doivent figurer dans la réponse. Cela évitera également certains problèmes désagréables que vous pourriez rencontrer avec les serveurs proxy qui pourraient ne pas gérer certaines réponses comme vous le souhaitez.

AVee
la source
18
HTTP est un protocole de niveau application. Vous ne pouvez pas le mettre simplement au niveau du transport et de l'application. Si vous pensez à OSI, HTTP est sur les couches 5-7. HTTP est quelque peu différent. La plupart des en-têtes et des codes de retour sont en effet spécifiques à l'application. Les codes dépendent uniquement des informations fournies dans les entités de protocole HTTP et non des éléments de format d'application personnalisé. Concernant les 200 je dirais que votre définition est purement fausse si elle est appliquée à des verbes n'étant pas POST. Mais POST change un peu la donne et dans ce contexte, votre hypothèse "gérée correctement" n'est pas sûre non plus
Norbert Hartl
À proprement parler, OSI considère HTTP comme un protocole de niveau application et lorsque l'on parle à un serveur Web «normal», c'est vrai. Mais dans votre cas, vous exécutez votre propre protocole en plus de HTTP, comme le font de nombreuses applications de nos jours. Dans ce type d'utilisation, HTTP fournit simplement le transport. (Votre application envoie des messages aux utilisateurs, pas de transfert d'hypertexte ...)
AVee
2
Juste pour être clair. HTTP de manière REST est centré sur les ressources. Dans ce contexte, 200 signifie identité (la ressource que vous avez spécifiée) au lieu de 3xx qui pointe dans la direction de l'identité. L'utilisation de POST transforme l'URI de la ressource en un URI de traitement et les codes d'erreur doivent y faire face. Le contexte change un peu et la définition des choses devient un peu floue ou du moins difficile à comprendre
Norbert Hartl
1
Le changement de contexte signifie également qu'il n'y a pas de codes d'erreur appropriés, car le protocole n'a jamais été conçu avec ce contexte à l'esprit ;-) Je pense également que vous devriez faire attention à l'utilisation de codes d'erreur car les serveurs proxy ont tendance à fonctionner en remplaçant votre réponse par un page d'erreur personnalisée, cela peut être un vrai PITA.
AVee
1
Quoi qu'il en soit, merci d'avoir répondu à ma question. Je viens de découvrir que stackoverflow est un mauvais client de chat :)
Norbert Hartl