¿Es incorrecto devolver 202 "Aceptado" en respuesta a HTTP GET?

89

Tengo un conjunto de recursos cuyas representaciones se crean con pereza. El cálculo para construir estas representaciones puede llevar desde unos pocos milisegundos hasta unas pocas horas, según la carga del servidor, el recurso específico y la fase de la luna.

La primera solicitud GET recibida para el recurso inicia el cálculo en el servidor. Si el cálculo se completa en unos segundos, se devuelve la representación calculada. De lo contrario, se devuelve un código de estado 202 "Aceptado" y el cliente debe sondear el recurso hasta que esté disponible la representación final.

El motivo de este comportamiento es el siguiente: si un resultado está disponible en unos pocos segundos, debe recuperarse lo antes posible; de lo contrario, cuando esté disponible no es importante.

Debido a la memoria limitada y al gran volumen de solicitudes, ni NIO ni el sondeo largo es una opción ( es decir, no puedo mantener abiertas suficientes conexiones, ni siquiera puedo ajustar todas las solicitudes en la memoria; una vez, "unos segundos" han pasado, persisto las solicitudes en exceso). Asimismo, las limitaciones del cliente son tales que no pueden manejar una devolución de llamada de finalización. Finalmente, tenga en cuenta que no estoy interesado en crear un recurso de "fábrica" ​​al que se envía un POST, ya que los viajes de ida y vuelta adicionales significan que fallamos en la restricción en tiempo real por partes más de lo deseado (además, es una complejidad adicional; también, este es un recurso que beneficiarse del almacenamiento en caché).

Me imagino que existe cierta controversia sobre la devolución de un código de estado 202 "Aceptado" en respuesta a una solicitud GET, ya que nunca lo he visto en la práctica, y su uso más intuitivo es en respuesta a métodos inseguros, pero nunca encontré algo específicamente desalentador. Además, ¿no estoy preservando tanto la seguridad como la idempotencia?

Entonces, ¿qué piensa la gente sobre este enfoque?

EDITAR : Debo mencionar que esto es para la llamada API web empresarial, no para navegadores.

usuario359996
fuente
2
Personalmente, creo que es bueno, es exactamente la definición de a 202. Que rara vez se usa en la práctica es en mi humilde opinión más porque pocos desarrolladores web se preocupan por los códigos de estado adecuados, ya que están más acostumbrados a la interacción navegador / usuario-agente, en cuyo caso 202a no les da una pista visible (dales un 200y estarán felices. ..).
Wrikken
1
@ user359996, solo usa 200. 202es lo que se supone que es, pero en la práctica la gente no espera 202.
Pacerier
sin embargo, necesita una ETA para que un 200 sea útil en la práctica.
Rob

Respuestas:

66

Si se trata de una API bien definida y documentada, 202suena exactamente bien para lo que está sucediendo.

Si es para la Internet pública, estaría demasiado preocupado por la compatibilidad del cliente. He visto tantos if (status == 200)codificados ... En ese caso, devolvería un 200.

Además, el RFC no indica que el uso de 202 para una solicitud GET sea incorrecto, mientras que hace distinciones claras en otras descripciones de código (por ejemplo, 200).

La solicitud ha sido aceptada para su procesamiento, pero el procesamiento no se ha completado.

Pekka
fuente
16

Hicimos esto para una aplicación reciente, un cliente (aplicación personalizada, no un navegador) publicó una consulta y el servidor devolvería 202 con un URI al "trabajo" que se estaba publicando; el cliente usaría ese URI para sondear el resultado: esto parece encajar muy bien con lo que se estaba haciendo.

De todos modos, lo más importante aquí es documentar cómo funciona su servicio / API y qué significa una respuesta de 202.

nos
fuente
+1 Gracias por tu comentario. Buen punto sobre la documentación. Pero tenga en cuenta las modificaciones aclaratorias de mi pregunta (busque "fábrica").
user359996
Bueno, puede omitir ese URI en la respuesta si solo desea sondear el mismo URI que solicitó inicialmente. (Solo documente cómo debería funcionar :-))
nos
Buena idea, pero recuerda que quiero almacenamiento en caché, así que no POST. Además, el URI especifica el recurso, no un método. Estoy tomando un enfoque RESTful, en lugar de RPC (lo siento, otra restricción no especificada, mi mal).
user359996
Para ser precisos, por "RESTful", en realidad me refiero a "orientado a recursos", que técnicamente es un poco más de lo especificado por las restricciones REST.
user359996
12

Por lo que puedo recordar, se supone que GET devuelve un recurso sin modificar el servidor. Tal vez se registre la actividad o lo que sea, pero la solicitud debería poder volver a ejecutarse con el mismo resultado.

POST, por otro lado, es una solicitud para cambiar el estado de algo en el servidor. Insertar un registro, eliminar un registro, ejecutar un trabajo, algo así. 202 sería apropiado para un POST que regresó pero no está terminado, pero no es realmente una solicitud GET.

Todo es muy puritano y no se practica bien en la naturaleza, por lo que probablemente esté seguro si regresa 202. GET debería devolver 200. POST puede devolver 200 si terminó o 202 si no lo hizo.

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

Dlongnecker
fuente
4
Muy bien pensado, pero no estoy seguro de si se aplica aquí: por lo que dice el OP, esta parece ser una solicitud GET adecuada (en el sentido de que no cambia nada en el servidor), solo lleva más tiempo calcular y en ese caso, se va a buscar en otro momento. Tal vez el OP pueda dar un comentario autorizado. Es para una API, por lo que está bien ser "puritano" por el bien de una interfaz limpia
Pekka
Oh, touche pekka. Tienes razón, GET es el camino a seguir. Y no creo que HTTP spc realmente tenga en cuenta los GET que no están listos. Para que pudiera ir de cualquier manera
Dlongnecker
7
Comentario autorizado (ahora irrelevante): Sí, lo veo como idempotente. El recurso no se está modificando ni creando, sino que su representación aún no se ha calculado.
user359996
1
¿Dónde dice eso? Además, si devuelvo 200, el cliente debería esperar que se haya devuelto una representación, pero no es así.
user359996
1
Me retracto. 202 no corresponde solo a GET o POST al parecer. La mentalidad en la que estaba cuando miré el protocolo me hizo pensar que 202 solo existía para solicitudes GET. 202 debería estar bien para sus propósitos.
Dlongnecker
0

En el caso de un recurso que se supone que tiene una representación de una entidad que está claramente especificada por un ID (a diferencia de un recurso de "fábrica", como se describe en la pregunta), recomiendo permanecer con el método GET y, en un Situación en la que la entidad / representación no está disponible debido a la creación diferida o cualquier otra situación temporal, use el código de respuesta 503 Servicio no disponible que es más apropiado y que en realidad fue diseñado para situaciones como esta.

El motivo de esto se puede encontrar en las RFC para HTTP en sí (verifique la descripción del código de respuesta 503), así como en muchos otros recursos.

Compárelo con el código de estado HTTP para las páginas que no están disponibles temporalmente . Aunque esa pregunta se trata de un caso de uso diferente, en realidad se relaciona exactamente con la misma característica de HTTP.

Hermes
fuente