rest - tesis - 400 vs 422 respuesta a POST de datos
tesis sobre netflix (9)
Estoy tratando de averiguar cuál es el código de estado correcto para regresar en diferentes escenarios con una API "tipo REST" en la que estoy trabajando. Digamos que tengo un punto final que permite realizar compras POST en formato JSON. Se parece a esto:
{
"account_number": 45645511,
"upc": "00490000486",
"price": 1.00,
"tax": 0.08
}
¿Qué debo devolver si el cliente me envía "sales_tax" (en lugar del "impuesto" esperado)? Actualmente, estoy devolviendo un 400. Pero, comencé a preguntarme sobre esto. ¿Realmente debería estar devolviendo un 422? Quiero decir, es JSON (que es compatible) y es JSON válido, simplemente no contiene todos los campos requeridos.
422 entidad no procesable explicada actualizada: 6 de marzo de 2017
¿Qué es la 422 entidad no procesable?
Un código de estado 422 se produce cuando una solicitud está bien formada, sin embargo, debido a errores semánticos no se puede procesar. Este estado HTTP se introdujo en RFC 4918 y está más específicamente orientado a las extensiones HTTP para la creación y control de versiones distribuidas en la web (WebDAV).
Existe cierta controversia sobre si los desarrolladores deben devolver un error 400 vs 422 a los clientes (más sobre las diferencias entre los dos estados a continuación). Sin embargo, en la mayoría de los casos, se acuerda que el estado 422 solo debe devolverse si es compatible con las capacidades de WebDAV.
La definición palabra por palabra del código de estado 422 tomada de la sección 11.2 en RFC 4918 se puede leer a continuación.
El código de estado 422 (entidad no procesable) significa que el servidor entiende el tipo de contenido de la entidad de solicitud (por lo tanto, un código de estado 415 (tipo de medio no admitido) es inadecuado), y la sintaxis de la entidad de solicitud es correcta (por lo tanto, un código de estado 400 (solicitud incorrecta) ) el código de estado es inapropiado) pero no pudo procesar las instrucciones contenidas.
La definición continúa diciendo:
Por ejemplo, esta condición de error puede ocurrir si un cuerpo de solicitud XML contiene instrucciones XML bien formadas (es decir, sintácticamente correctas), pero semánticamente erróneas.
400 vs 422 códigos de estado
Los errores de solicitud incorrecta utilizan el código de estado 400 y deben devolverse al cliente si la sintaxis de la solicitud tiene un formato incorrecto, contiene una trama de mensaje de solicitud no válida o tiene un enrutamiento de solicitud engañoso. Este código de estado puede parecer bastante similar al estado de la entidad no procesable 422, sin embargo, una pequeña parte de la información que los distingue es el hecho de que la sintaxis de una entidad de solicitud para un error 422 es correcta, mientras que la sintaxis de una solicitud que genera un 400 el error es incorrecto
El uso del estado 422 debe reservarse solo para casos de uso muy particulares. En la mayoría de los otros casos en los que se ha producido un error de cliente debido a una sintaxis mal formada, se debe utilizar el estado 400 Solicitud incorrecta.
En primer lugar esta es una muy buena pregunta.
400 Solicitud incorrecta: cuando falta información importante en la solicitud
Por ejemplo, el encabezado de autorización o el encabezado de tipo de contenido. Lo cual es absolutamente requerido por el servidor para entender la solicitud. Esto puede diferir de un servidor a otro.
422 Entidad no procesable: cuando el cuerpo de la solicitud no se puede analizar.
Esto es menos grave que 400. La solicitud ha llegado al servidor. El servidor ha reconocido que la solicitud tiene la estructura básica correcta. Pero la información en el cuerpo de solicitud no puede ser analizada o entendida.
por ejemplo, Content-Type: application/xml
cuando el cuerpo de la solicitud es JSON.
Aquí hay un artículo con los códigos de estado y su uso en las API REST. https://metamug.com/article/status-codes-for-rest-api.php
En realidad, debe devolver "200 OK" y en el cuerpo de la respuesta incluir un mensaje sobre lo que sucedió con los datos publicados. Entonces depende de tu aplicación entender el mensaje.
La cosa es que los códigos de estado HTTP son exactamente eso: códigos de estado HTTP. Y están destinados a tener un significado solo en la capa de transporte, no en la capa de aplicación. La capa de aplicación realmente nunca debería saber que se está utilizando HTTP. Si cambió su capa de transporte de HTTP a Homing Pigeons, no debería afectar su capa de aplicación de ninguna manera.
Déjame darte un ejemplo no virtual. Digamos que te enamoras de una chica y ella te quiere, pero su familia se muda a un país completamente diferente. Ella te da su nueva dirección de correo electrónico. Naturalmente, usted decide enviarle una carta de amor. Así que escribes tu carta, la pones en un sobre, escribes su dirección en el sobre, le pones un sello y la envías. Ahora consideremos estos escenarios.
- Se te olvidó escribir un nombre de calle. Recibirá una carta sin abrir con un mensaje escrito que dice que la dirección tiene un formato incorrecto. Usted arruinó la solicitud y la oficina de correos receptora no puede manejarla. Eso es el equivalente de recibir "400 Bad Request".
- Así que arregla la dirección y vuelve a enviar la carta. Pero debido a un poco de mala suerte, usted deletreó mal el nombre de la calle. Recibirá la carta nuevamente con un mensaje que dice que la dirección no existe. Eso es el equivalente a recibir "404 No encontrado".
- Corrige la dirección nuevamente y esta vez logras escribir la dirección correctamente. Tu chica recibe la carta y te contesta. Es el equivalente a recibir "200 OK". Sin embargo, esto no significa que le gustará lo que escribió en su carta. Simplemente significa que recibió su mensaje y tiene una respuesta para usted. Hasta que no abra el sobre y lea su carta, no podrá saber si lo extraña mucho o si quiere romper con usted.
En resumen: devolver "200 OK" no significa que la aplicación del servidor tenga buenas noticias para usted. Solo significa que tiene alguna noticia.
PD: El código de estado 422 tiene un significado solo en el contexto de WebDAV. Si no está trabajando con WebDAV, 422 tiene exactamente el mismo significado estándar que cualquier otro código no estándar = que no es ninguno.
No hay una respuesta correcta, ya que depende de cuál sea la definición de "sintaxis" para su solicitud. Lo más importante es que tú:
- Usa el código (s) de respuesta consistentemente
- Incluya tanta información adicional en el cuerpo de la respuesta como pueda para ayudar a los desarrolladores que usan su API a descubrir qué está pasando. =
Antes de que todos salten sobre mí por decir que no hay una respuesta correcta o incorrecta aquí, permítanme explicarles un poco sobre cómo llegué a la conclusión.
En este ejemplo específico, la pregunta del OP es sobre una solicitud JSON que contiene una clave diferente a la esperada. Ahora, el nombre de la clave recibida es muy similar, desde el punto de vista del lenguaje natural, a la clave esperada, pero es, estrictamente, diferente y, por lo tanto, una máquina no la reconoce como equivalente.
Como dije anteriormente, el factor decisivo es lo que se entiende por sintaxis . Si la solicitud se envió con un Tipo de contenido de application/json
, entonces sí, la solicitud es sintácticamente válida porque es una sintaxis JSON válida, pero no semánticamente válida, ya que no coincide con lo que se espera. (Suponiendo una definición estricta de lo que hace que la solicitud en cuestión sea semánticamente válida o no).
Si, por otro lado, la solicitud se envió con un tipo de contenido personalizado más específico como application/vnd.mycorp.mydatatype+json
que, tal vez, especifique exactamente qué campos se esperan, entonces diría que la solicitud podría fácilmente ser sintáctica. inválido, de ahí la respuesta 400.
En el caso en cuestión, dado que la clave era incorrecta, no el valor , había un error de sintaxis si existía una especificación de qué claves son válidas. Si no hubiera una especificación para las claves válidas, o el error fue con un valor , entonces sería un error semántico .
400 Bad Request ahora parece ser el mejor código de estado HTTP / 1.1 para su caso de uso.
En el momento de su pregunta (y mi respuesta original), RFC 7231 no era una cosa; en ese punto me opuse a 400 Bad Request
porque RFC 2616 dijo (con énfasis mío):
El servidor no pudo comprender la solicitud debido a una sintaxis mal formada .
y la solicitud que usted describe es JSON válida sintácticamente incluida en HTTP válido sintácticamente, y por lo tanto el servidor no tiene problemas con la sintaxis de la solicitud.
Sin embargo, como lo señaló Lee Saferite en los comentarios , RFC 7231, que obsoleta RFC 2616, no incluye esa restricción :
El código de estado 400 (Solicitud errónea) 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 mal formada, trama de mensajes de solicitud no válida o enrutamiento de solicitud engañosa).
Sin embargo, antes de la nueva redacción (o si desea discutir con RFC 7231 por ser solo un estándar propuesto en este momento), la 422 Unprocessable Entity
no 422 Unprocessable Entity
no parece ser un código de estado HTTP incorrecto para su caso de uso, porque como introducción a RFC 4918 dice:
Si bien los códigos de estado proporcionados por HTTP / 1.1 son suficientes para describir la mayoría de las condiciones de error encontradas por los métodos de WebDAV, hay algunos errores que no caen claramente en las categorías existentes. Esta especificación define códigos de estado adicionales desarrollados para los métodos de WebDAV (Sección 11)
Y la descripción de 422
dice:
El código de estado 422 (entidad no procesable) significa que el servidor entiende el tipo de contenido de la entidad de solicitud (por lo tanto, un código de estado 415 (tipo de medio no admitido) es inadecuado), y la sintaxis de la entidad de solicitud es correcta (por lo tanto, un código de estado 400 (solicitud incorrecta) ) el código de estado es inapropiado) pero no pudo procesar las instrucciones contenidas.
(Tenga en cuenta la referencia a la sintaxis; sospecho que el 7231 está parcialmente obsoleto, también el 4918)
Esto suena exactamente como su situación, pero en caso de que hubiera alguna duda, continúa diciendo:
Por ejemplo, esta condición de error puede ocurrir si un cuerpo de solicitud XML contiene instrucciones XML bien formadas (es decir, sintácticamente correctas), pero semánticamente erróneas.
(Reemplace "XML" con "JSON" y creo que podemos estar de acuerdo en que es su situación)
Ahora, algunos objetarán que RFC 4918 se trata de "Extensiones HTTP para la creación y control de versiones distribuidas en la web (WebDAV)" y que (presumiblemente) usted no está haciendo nada que involucre a WebDAV, por lo que no debería usarlo.
Dada la opción entre usar un código de error en el estándar original que explícitamente no cubre la situación y uno de una extensión que describe la situación exactamente, elegiría esta última.
Además, RFC 4918 Sección 21.4 se refiere al Registro de códigos de estado del Protocolo de transferencia de hipertexto (HTTP) de la IANA , donde se pueden encontrar 422.
Propongo que es totalmente razonable que un cliente o servidor HTTP use cualquier código de estado de ese registro, siempre y cuando lo haga correctamente.
Pero a partir de HTTP / 1.1, RFC 7231 tiene tracción, ¡así que solo use 400 Bad Request
!
400 Bad Request es el código de estado HTTP adecuado para su caso de uso. El código está definido por HTTP / 0.9-1.1 RFC.
El servidor no pudo comprender la solicitud debido a una sintaxis mal formada. El cliente NO DEBE repetir la solicitud sin modificaciones.
http://tools.ietf.org/html/rfc2616#section-10.4.1
422 La entidad no procesable está definida por RFC 4918 - WebDav. Tenga en cuenta que hay una ligera diferencia en comparación con 400, consulte el texto citado a continuación.
Esta condición de error puede ocurrir si un cuerpo de solicitud XML contiene instrucciones XML bien formadas (es decir, sintácticamente correctas), pero semánticamente erróneas.
Para mantener la interfaz uniforme, debe usar 422 solo en el caso de respuestas XML y también debe admitir todos los códigos de estado definidos por la extensión Webdav, no solo 422.
http://tools.ietf.org/html/rfc4918#page-78
Véase también la publicación de Mark Nottingham sobre códigos de estado:
es un error tratar de asignar cada parte de su aplicación "profundamente" a los códigos de estado HTTP; en la mayoría de los casos, el nivel de granularidad al que se desea apuntar es mucho más basto. En caso de duda, está bien utilizar los códigos de estado genéricos 200 Aceptar, 400 Solicitud incorrecta y 500 Error de servicio interno cuando no haya un mejor ajuste .
Caso de estudio: API de GitHub
https://developer.github.com/v3/#client-errors
Tal vez copiar de APIs bien conocidas es una buena idea:
Hay tres tipos posibles de errores de cliente en las llamadas a la API que reciben cuerpos de solicitud:
Enviar un JSON no válido dará como resultado una respuesta de 400 Solicitudes erróneas.
HTTP/1.1 400 Bad Request Content-Length: 35 {"message":"Problems parsing JSON"}
Enviar el tipo incorrecto de valores JSON resultará en una respuesta de 400 Solicitudes erróneas.
HTTP/1.1 400 Bad Request Content-Length: 40 {"message":"Body should be a JSON object"}
El envío de campos no válidos dará lugar a una respuesta de la entidad no procesable 422.
HTTP/1.1 422 Unprocessable Entity Content-Length: 149 { "message": "Validation Failed", "errors": [ { "resource": "Issue", "field": "title", "code": "missing_field" } ] }
Para reflejar el estado a partir de 2015:
De manera conductual, los códigos de respuesta 400 y 422 serán tratados de la misma manera por los clientes e intermediarios, por lo que en realidad no hace una diferencia concreta que usted use.
Sin embargo, espero ver el uso actual de 400 más ampliamente y, además, las aclaraciones que proporciona la especificación HTTPbis hacen que sea el más apropiado de los dos códigos de estado:
- La especificación de HTTPbis aclara la intención de 400 de no ser únicamente para errores de sintaxis. La frase más amplia "indica que el servidor no puede o no procesará la solicitud debido a algo que se percibe como un error del cliente" ahora se usa.
- 422 Es específicamente una extensión de WebDAV, y no se hace referencia en RFC 2616 o en la nueva especificación de HTTPbis .
Para el contexto, HTTPbis es una revisión de la especificación HTTP / 1.1 que intenta aclarar áreas que no eran claras o inconsistentes. Una vez que haya alcanzado el estado aprobado, reemplazará a RFC2616.
Su caso: HTTP 400
es el código de estado correcto para su caso desde la perspectiva REST, ya que es sintácticamente incorrecto para enviar el sales_tax
a las sales_tax
lugar de tax
, aunque es un JSON válido. Normalmente, esto se aplica en la mayoría de los marcos del lado del servidor cuando se asigna el JSON a los objetos. Sin embargo, hay algunas implementaciones REST que ignoran la nueva key
en el objeto JSON. En ese caso, el lado del servidor puede imponer una especificación de content-type
personalizado para aceptar solo campos válidos.
Escenario ideal para 422:
En un mundo ideal, 422 es preferible y generalmente aceptable para enviar como respuesta si el servidor entiende el tipo de contenido de la entidad de solicitud y la sintaxis de la entidad de solicitud es correcta pero no pudo procesar los datos debido a que es semánticamente errónea.
Situaciones de 400 sobre 422:
Recuerde, el código de respuesta 422 es un código de estado HTTP extendido (WebDAV). Todavía hay algunos clientes HTTP / bibliotecas front-end que no están preparados para manejar 422. Para ellos, es tan simple como "HTTP 422 es incorrecto, porque no es HTTP" . Desde la perspectiva del servicio, 400 no es muy específico.
En la arquitectura empresarial, los servicios se implementan principalmente en capas de servicios como SOA, IDM, etc. Por lo general, atienden a múltiples clientes que van desde un cliente nativo muy antiguo hasta un cliente HTTP más reciente. Si uno de los clientes no maneja HTTP 422, las opciones son pedirle al cliente que actualice o cambie su código de respuesta a HTTP 400 para todos. En mi experiencia, esto es muy raro en estos días, pero sigue siendo una posibilidad. Por lo tanto, siempre se requiere un estudio cuidadoso de su arquitectura antes de decidir sobre los códigos de respuesta HTTP.
Para manejar una situación como esta, las capas de servicio normalmente usan el versioning
o la configuración de la configuration
para que los clientes de conformidad HTTP estrictos envíen 400 y envían 422 para el resto de ellos. De esa manera, proporcionan compatibilidad con versiones anteriores para los consumidores existentes, pero al mismo tiempo brindan la capacidad para que los nuevos clientes consuman HTTP 422.
La última actualización de RFC7321 dice:
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
Esto confirma que los servidores pueden enviar HTTP 400 para una solicitud no válida. 400 ya no se refiere solo al error de sintaxis , sin embargo, 422 sigue siendo una respuesta genuina siempre que los clientes puedan manejarlo.