Digamos que tengo un punto final REST que toma un entero como parámetro:
/makeWaffles?numberOfWaffles=3
En este caso, quiero que el número sea positivo porque no puedo hacer un número negativo de gofres (y solicitar 0 gofres es una pérdida de tiempo). Por lo tanto, quiero rechazar cualquier solicitud que no contenga un entero positivo. También quiero rechazar una solicitud que exceda un número entero máximo (digamos por ahora que es MAX_INTEGER).
En el caso de que alguien solicite un número no positivo de gofres, ¿debo devolver un estado HTTP 400 (Solicitud incorrecta)? Mi pensamiento inicial es sí: no es un número válido para completar la solicitud. Sin embargo, el RFC no menciona las reglas comerciales como una razón para lanzarlo:
El código de estado 400 (Solicitud incorrecta) indica que el servidor no puede o no procesará la solicitud debido a algo que se percibe como un error del cliente (por ejemplo, sintaxis de solicitud con formato incorrecto, enmarcado de mensaje de solicitud no válido o enrutamiento de solicitud engañoso).
Una regla de negocios no se incluye en ninguno de esos tres ejemplos. Es sintácticamente correcto, está enmarcado correctamente y no es una ruta de solicitud engañosa.
Entonces, ¿debo devolver un estado HTTP 400 (Solicitud incorrecta) si un parámetro es sintácticamente correcto, pero viola una regla comercial? ¿O hay un estado más apropiado para regresar?
fuente
Respuestas:
Esta es una gran pregunta, y sigue siendo muy relevante dado el contexto histórico (y definiciones aparentemente contradictorias) de los códigos de retorno HTTP. Incluso entre las respuestas a esta pregunta hay definiciones contradictorias. Esto se puede aclarar moviéndose cronológicamente.
RFC 2616 (junio de 1999)
A partir de este RFC, este código de estado se aplica específicamente solo a solicitudes sintácticamente inválidas. Hubo una brecha en los códigos de estado para la validación semántica. Por lo tanto, cuando apareció RFC 4918, nació un nuevo código.
RFC 4918 (junio de 2007)
422 Entidad no procesable se creó para llenar el vacío de validación semántica en la especificación original de los códigos de estado 4xx. Sin embargo, se produjo otro RFC relevante en 2014 que generalizó 400 para que ya no sea específico de la sintaxis .
RFC 7231 (junio de 2014, explícitamente obsoletos RFC 2616)
Tenga en cuenta que la descripción de 422 dice que la razón por la que 400 es inapropiada es porque 400 (a partir de RFC 2616) debe devolverse solo por una sintaxis de solicitud incorrecta. Sin embargo, a partir de RFC 7231, la definición estricta de error de sintaxis ya no se aplica a 400 .
Volviendo a la pregunta en cuestión: si bien 422 es técnicamente más específico, dado este contexto, pude ver que 400 o 422 se usan para la validación semántica de los parámetros API. Dudo en usar 422 en mis propias API porque la definición de 422 está técnicamente desactualizada en este momento (aunque no sé si eso se reconoce oficialmente en alguna parte). El artículo al que se hace referencia en la respuesta de Fran que alienta el uso de 422 fue escrito en 2012, dos años antes de que RFC 7231 aclarara HTTP 400. Solo asegúrese de estandarizar uno u otro.
fuente
Leí la primera respuesta y realmente no estuve de acuerdo con ella porque, al menos en mi lectura, una solicitud incorrecta (400) significa: "Ni siquiera puedo manejar su solicitud porque algo está fundamentalmente mal". Y encontré esta publicación que justifica la devolución de un 422.
de IETF
422 Entidad no procesable (WebDAV; RFC 4918) La solicitud estaba bien formada pero no se pudo seguir debido a errores semánticos
Esto parece una respuesta más apropiada ya que su solicitud está bien formada, pero no pasa sus reglas de validación.
fuente
No, no deberías. Los códigos HTTP están destinados a la capa HTTP de su aplicación. Las reglas de negocio son completamente diferentes y son específicas de la aplicación, por lo que debe crear su propio "protocolo".
Imagina que sucede un apocalipsis y tienes que cambiar del protocolo HTTP a usar Pigeons. Las palomas no tienen ningún código de retorno, por lo que deberá cambiar su capa de negocios para adaptarse a eso. Pero su negocio realmente no ha cambiado de ninguna manera, por lo que no debería necesitar cambiar la capa empresarial. Muestra un fuerte acoplamiento entre esas dos capas (transporte y negocios).
Volver a la pregunta: lo que debe hacer es devolver "200 OK" con un cuerpo que describa lo que sucedió con la solicitud. La especificación lo dice claramente:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1 .
¿Tu solicitud HTTP tuvo éxito? Sí, el servidor web sabe qué hacer con esa solicitud (por ejemplo, pasarla a la parte del servidor de su aplicación). El servidor web luego pasa esta solicitud a la parte del servidor de su aplicación, que toma los datos PUBLICADOS, los procesa (los valida en su caso) y devuelve una respuesta normal (en el cuerpo de una respuesta HTTP) a la parte del cliente de su aplicación . Esta respuesta de la parte del servidor de la aplicación puede ser "Excelente, los datos que me envió son válidos" o "Lo siento, los datos que envió no son válidos". Y depende de su cliente parte de la aplicación comprender lo que significa la respuesta.
PD: "400 Bad Request" significa que el servidor web no entendió lo que quieres de él. Significa que su servidor parte de su aplicación ni siquiera recibió la solicitud. O al menos eso es lo que significa :-)
EDITAR : Me acabo de dar cuenta de que estás haciendo una solicitud GET, no POST. Esta es una mala idea porque GET no debería cambiar el estado de la aplicación. Se supone que GET simplemente recupera datos del servidor. Pero en su solicitud, en realidad está cambiando el estado de la aplicación, por lo que realmente debería usar POST.
fuente
Sí, la entrada que no sigue el contrato implícito del punto final es "algo que se percibe como un error del cliente" y debe devolver 400.
Las excepciones a esto son si la regla de negocio está relacionada con la seguridad (entonces
401 Unauthorized
o403 Forbidden
sería mejor). Alternativamente, si enviar un 400 filtraría información sobre la existencia de algo, y luego404 Not Found
puede ser más apropiado.fuente
No estoy seguro de que todos estén de acuerdo, pero estamos usando 409 - Conflicto. Muchos afirman que el 409 es más un conflicto con el estado del sistema, pero aceptamos la interpretación de que un conflicto de valores de datos que están fuera del rango aceptado es reparable por el solicitante y un uso aceptable de 409. 422 Creo que sería razonable como la solicitud está formado correctamente pero no se puede procesar según lo solicitado. Sin embargo, opino que si no desea implementar una gran cantidad de respuestas, simplemente dar 400 todavía es aceptable.
fuente