codigos - error http
Códigos de estado HTTP REST para validación fallida o duplicado no válido (8)
Estoy creando una aplicación con una API basada en REST y he llegado al punto en el que estoy especificando códigos de estado para cada solicitud.
¿Qué código de estado debo enviar para las solicitudes que fallan en la validación o cuando una solicitud está tratando de agregar un duplicado en mi base de datos?
He buscado en http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html pero ninguno de ellos parece correcto.
¿Existe una práctica común al enviar códigos de estado?
200,300, 400, 500 son todos muy genéricos. Si quieres genérico, 400 está bien.
422 es usado por un número creciente de API, e incluso es usado por Rails fuera de la caja.
No importa qué código de estado elija para su API, alguien no estará de acuerdo. Pero prefiero 422 porque pienso que ''400 + estado de texto'' es demasiado genérico. Además, no estás aprovechando un analizador listo para JSON; en contraste, un 422 con una respuesta JSON es muy explícito y puede transmitirse una gran cantidad de información de errores.
Hablando de la respuesta de JSON, tiendo a estandarizar la respuesta de error de Rails para este caso, que es:
{
"errors" :
{
"arg1" : ["error msg 1", "error msg 2", ...]
"arg2" : ["error msg 1", "error msg 2", ...]
}
}
Este formato es perfecto para la validación de formularios, que considero el caso más complejo para admitir en términos de ''riqueza de informes de errores''. Si su estructura de error es esta, probablemente manejará todas sus necesidades de informe de errores.
El adaptador ActiveRecord de Ember-Data espera que 422 UNPROCESSABLE ENTITY
sea devuelta desde el servidor. Por lo tanto, si su cliente está escrito en Ember.js, debe usar 422. Solo entonces DS.Errors se rellenará con los errores devueltos. Por supuesto, puede cambiar 422 a cualquier otro código en su adaptador.
Para error de validación de entrada: 400 Solicitud incorrecta + su descripción opcional. Esto se sugiere en el libro " Servicios Web RESTful ". Para doble envío: 409 Conflicto
Actualización junio 2014
La especificación relevante solía ser RFC2616 , que daba el uso de 400 (Solicitud incorrecta) de forma bastante restringida como
El servidor no pudo comprender la solicitud debido a una sintaxis mal formada
Por lo tanto, podría haberse argumentado que era inapropiado para los errores semánticos. Pero ya no más; desde junio de 2014, el estándar relevante RFC 7231 , que reemplaza al anterior RFC2616, otorga el uso de 400 (Solicitud incorrecta) más ampliamente como
el servidor no puede o no procesará la solicitud debido a algo que se percibe como un error del cliente
Recomiendo el código de estado 422, "Entidad no procesable" .
11.2. 422 Entidad no procesable
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. 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.
Un duplicado en la base de datos debe ser un 409 CONFLICT
.
Recomiendo usar la 422 UNPROCESSABLE ENTITY
para errores de validación.
Doy una explicación más larga de los códigos 4xx aquí: http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/
El Código de estado 304 No modificado también daría una respuesta aceptable a una solicitud duplicada. Esto es similar a procesar un encabezado de If-None-Match
usando una etiqueta de entidad.
En mi opinión, la respuesta de @ Piskvor es la elección más obvia de lo que percibo es la intención de la pregunta original, pero tengo una alternativa que también es relevante.
Si desea tratar una solicitud duplicada como una advertencia o notificación en lugar de un error, un código de estado de respuesta de 304
No modificado y el encabezado de Content-Location
identifique el recurso existente sería igual de válido. Cuando la intención es meramente asegurar que exista un recurso, una solicitud duplicada no sería un error sino una confirmación. La solicitud no está mal, pero es simplemente redundante, y el cliente puede referirse al recurso existente.
En otras palabras, la solicitud es buena, pero como el recurso ya existe, el servidor no necesita realizar ningún procesamiento adicional.
200
Ugh ... (309, 400, 403, 409, 415, 422) ... muchas respuestas que intentan adivinar, argumentar y estandarizar cuál es el mejor código de retorno para una solicitud http exitosa pero una llamada de reposo fallida .
Es incorrecto mezclar códigos de protocolo HTTP y resultados REST.
Sin embargo, vi muchas implementaciones mezclándolas y muchos desarrolladores pueden no estar de acuerdo conmigo.
Los códigos de retorno HTTP están relacionados con la HTTP Request
sí. Una llamada REST se realiza mediante una solicitud de Protocolo de transferencia de hipertexto y funciona a un nivel más bajo que el propio método REST invocado. REST es un concepto / enfoque, y su salida es un resultado comercial / lógico , mientras que el código de resultado HTTP es uno de transporte .
Por ejemplo, devolver "404 No encontrado" cuando llama / users / es confuso, porque puede significar:
- URI está mal (HTTP)
- No se encontraron usuarios (REST)
"403 Prohibido / Acceso denegado" puede significar:
- Se necesita un permiso especial. Los navegadores pueden manejarlo preguntando al usuario / contraseña. (HTTP)
- Permisos de acceso erróneos configurados en el servidor. (HTTP)
- Necesitas estar autenticado (REST)
Y la lista puede continuar con ''500 Error de servidor "(un error de lanzamiento de Apache / Nginx HTTP o un error de restricción empresarial en REST) u otros errores de HTTP, etc.
Desde el código, es difícil entender cuál fue el motivo del error, un error HTTP (transporte) o un error REST (lógico).
Si la solicitud HTTP se realizó físicamente con éxito, siempre debería devolver el código 200, independientemente de si se encontraron los registros o no. Debido a que el recurso URI se encuentra y fue manejado por el servidor http. Sí, puede devolver un conjunto vacío. ¿Es posible recibir una página web vacía con 200 como resultado de http, verdad?
En lugar de esto, puede devolver 200 códigos HTTP con algunas opciones:
- Objeto "error" en el resultado JSON si algo sale mal
- Array / objeto JSON vacío si no se encuentra ningún registro
- Un indicador de resultado / éxito bool en combinación con las opciones anteriores para un mejor manejo.
Además, algunos proveedores de Internet pueden interceptar sus solicitudes y devolverle un código HTTP 404. Esto no significa que no se encuentren sus datos, pero es algo incorrecto en el nivel de transporte.
De Wiki :
En julio de 2004, el proveedor de telecomunicaciones del Reino Unido BT Group implementó el sistema de bloqueo de contenido Cleanfeed, que devuelve un error 404 a cualquier solicitud de contenido identificado como potencialmente ilegal por Internet Watch Foundation. Otros ISP devuelven un error "prohibido" de HTTP 403 en las mismas circunstancias. La práctica de emplear errores 404 falsos como un medio para ocultar la censura también se ha informado en Tailandia y Túnez. En Túnez, donde la censura era severa antes de la revolución de 2011, la gente se dio cuenta de la naturaleza de los errores falsos 404 y creó un personaje imaginario llamado "Ammar 404" que representa "el censor invisible".
¿Por qué no simplemente responder con algo como esto?
{
"result": false,
"error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}
Google siempre devuelve 200 como código de estado en su API de codificación geográfica, incluso si la solicitud falla lógicamente: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes
- Validación fallida: 403 Prohibido ("El servidor entendió la solicitud, pero se niega a cumplirla"). Contrariamente a la opinión popular, RFC2616 no dice "403 solo está destinado a una autenticación fallida", sino "403: Sé lo que quieres, pero no lo haré". Esa condición puede o no deberse a la autenticación.
- Intentando agregar un duplicado: 409 Conflicto ("La solicitud no se pudo completar debido a un conflicto con el estado actual del recurso")
Definitivamente, debe dar una explicación más detallada en los encabezados de respuesta y / o el cuerpo (por ejemplo, con un encabezado personalizado - X-Status-Reason: Validation failed
).