Est-il erroné de renvoyer 202 «Accepté» en réponse à HTTP GET?

89

J'ai un ensemble de ressources dont les représentations sont créées paresseusement. Le calcul pour construire ces représentations peut prendre de quelques millisecondes à quelques heures, selon la charge du serveur, la ressource spécifique et la phase de la lune.

La première requête GET reçue pour la ressource démarre le calcul sur le serveur. Si le calcul se termine en quelques secondes, la représentation calculée est renvoyée. Sinon, un code d'état 202 "Accepté" est renvoyé et le client doit interroger la ressource jusqu'à ce que la représentation finale soit disponible.

La raison de ce comportement est la suivante: si un résultat est disponible en quelques secondes, il doit être récupéré dès que possible; sinon, quand il devient disponible n'est pas important.

En raison de la mémoire limitée et du volume considérable de demandes, ni NIO ni longue interrogation ne sont une option ( c'est-à-dire que je ne peux pas garder presque assez de connexions ouvertes, ni même que je ne peux même pas mettre toutes les demandes en mémoire; une fois "quelques secondes" ont passé, je persiste les demandes en excès). De même, les limitations des clients sont telles qu'ils ne peuvent pas gérer un rappel d'achèvement à la place. Enfin, notez que je ne suis pas intéressé par la création d'une ressource "usine" à laquelle on POST, car les allers-retours supplémentaires signifient que nous échouons à la contrainte temps réel par morceaux plus que ce qui est souhaité (de plus, c'est une complexité supplémentaire; aussi, c'est une ressource qui bénéficier de la mise en cache).

J'imagine qu'il y a une controverse sur le renvoi d'un code de statut 202 "Accepté" en réponse à une requête GET, car je ne l'ai jamais vu dans la pratique, et son utilisation la plus intuitive est en réponse à des méthodes non sécurisées, mais je n'ai jamais trouvé quelque chose qui le décourageait spécifiquement. De plus, est-ce que je ne préserve pas à la fois la sécurité et l'idempotence?

Alors, que pensent les gens de cette approche?

EDIT : Je devrais mentionner que c'est pour une soi-disant API Web d'entreprise - pas pour les navigateurs.

user359996
la source
2
Personnellement, je pense que c'est une bonne, c'est exactement la définition d'un 202. Le fait qu'il soit rarement utilisé dans la pratique est plus IMHO parce que peu de développeurs Web se soucient des codes de statut appropriés car ils sont plus habitués à l'interaction navigateur / utilisateur-agent, auquel cas a 202ne leur donne aucun indice visible (donnez-leur un 200et ils sont heureux. ..).
Wrikken
1
@ user359996, utilisez simplement 200. 202est ce que c'est censé être, mais dans la pratique, les gens ne s'attendent pas 202.
Pacerier
il a besoin d'un ETA pour qu'un 200 soit utile dans la pratique.
Rob

Réponses:

66

Si c'est pour une API bien définie et documentée, ça 202sonne exactement pour ce qui se passe.

Si c'est pour l'Internet public, je serais trop préoccupé par la compatibilité des clients. J'ai vu tellement de if (status == 200)codes en dur ... Dans ce cas, je retournerais un fichier 200.

De plus, la RFC n'indique pas que l'utilisation de 202 pour une demande GET est erronée, alors qu'elle fait des distinctions claires dans d'autres descriptions de code (par exemple 200).

La demande a été acceptée pour traitement, mais le traitement n'est pas terminé.

Pekka
la source
15

Nous l'avons fait pour une application récente, un client (application personnalisée, pas un navigateur) POST une requête et le serveur renverra 202 avec un URI pour le "travail" en cours de publication - le client utilisera cet URI pour interroger le résultat - cela semble bien cadrer avec ce qui était fait.

Le plus important ici est de toute façon de documenter le fonctionnement de votre service / API et ce que signifie une réponse de 202.

nos
la source
+1 Merci pour votre commentaire. Bon point sur la documentation. Mais s'il vous plaît noter les modifications de clarification à ma question (recherchez "usine").
user359996
Eh bien, vous pouvez omettre cet URI dans la réponse si vous souhaitez simplement interroger le même URI que celui que vous avez initialement demandé. (Documentez simplement comment cela devrait fonctionner :-))
nos
Bonne idée, mais rappelez-vous que je veux la mise en cache, donc pas de POST. De plus, l'URI spécifie la ressource, pas une méthode. Je prends une approche RESTful, plutôt que RPC (désolé, une autre contrainte non spécifiée - ma mauvaise).
user359996
Pour être précis, par "RESTful", je veux dire en fait "orienté ressources", ce qui est techniquement un peu plus que ce qui est spécifié par les contraintes REST.
user359996
12

D'après ce dont je me souviens, GET est censé renvoyer une ressource sans modifier le serveur. Peut-être que l'activité sera enregistrée ou quoi que ce soit d'autre, mais la demande devrait être renouvelable avec le même résultat.

POST, d'autre part, est une demande de changement d'état de quelque chose sur le serveur. Insérez un enregistrement, supprimez un enregistrement, exécutez un travail, quelque chose comme ça. 202 serait approprié pour un POST qui est retourné mais n'est pas terminé, mais pas vraiment une requête GET.

Tout est très puritain et pas bien pratiqué dans la nature, donc vous êtes probablement en sécurité en renvoyant 202. GET devrait renvoyer 200. POST peut renvoyer 200 s'il est terminé ou 202 si ce n'est pas fait.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Dlongnecker
la source
4
Très bonne réflexion mais je ne suis pas sûr que cela s'applique ici: d'après ce que dit l'OP, cela semble être une requête GET appropriée (en ce sens qu'elle ne change rien sur le serveur), cela prend juste plus de temps à calculer et à ce cas, doit être récupéré à un autre moment. Peut-être que le PO peut donner un commentaire faisant autorité. C'est pour une API, donc c'est bien d'être "puritain" pour le bien d'une interface propre
Pekka
Oh, touche pekka. Vous avez raison, GET est la voie à suivre. Et je ne pense pas que le HTTP SPC ait vraiment pris en compte les GET qui ne sont pas prêts. Donc il pourrait aller dans les deux sens
Dlongnecker
7
(Désormais non pertinent) Commentaire faisant autorité: Oui, je considère cela comme idempotent. La ressource n'est ni modifiée ni créée, mais sa représentation n'a pas encore été calculée.
user359996
1
Où dit-il cela? De plus, si je renvoie 200, le client doit s'attendre à ce qu'une représentation ait été renvoyée, mais ce n'est pas le cas.
user359996
1
Je reprend cela. 202 ne correspond pas seulement à GET ou POST semble-t-il. L'état d'esprit dans lequel j'étais quand j'ai regardé le protocole m'a fait que le 202 n'existait que pour les demandes GET. 202 devrait convenir à vos besoins.
Dlongnecker
0

Dans le cas d'une ressource censée avoir une représentation d'une entité clairement spécifiée par un identifiant (par opposition à une ressource "usine", comme décrit dans la question), je recommande de rester avec la méthode GET et, dans un situation où l'entité / représentation n'est pas disponible en raison d'une création paresseuse ou de toute autre situation temporaire, utilisez le code de réponse 503 Service Indisponible qui est plus approprié et qui a en fait été conçu pour des situations comme celle-ci.

Le raisonnement pour cela peut être trouvé dans les RFC pour HTTP lui-même (veuillez vérifier la description du code de réponse 503), ainsi que sur de nombreuses autres ressources.

Veuillez comparer avec le code d'état HTTP pour les pages temporairement indisponibles . Bien que cette question porte sur un cas d'utilisation différent, elle concerne en fait exactement la même fonctionnalité de HTTP.

Hermès
la source