Códigos de estado HTTP REST para validación fallida o duplicado no válido


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 mirado a través de 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?

Author: Raedwald, 2010-07-20

8 answers

Para error de validación de entrada: 400 Solicitud incorrecta + su descripción opcional. Esto se sugiere en el libro " RESTful Web Services". Para double submit: 409 Conflict


Actualización de junio de 2014

La especificación relevante solía ser RFC2616 , que dio el uso de 400 (Solicitud incorrecta) de forma bastante restringida como

El servidor no pudo entender la solicitud debido a una sintaxis mal formada

Así que podría haber sido argumentado que era inapropiado para errores semánticos. Pero ya no; desde junio de 2014, la norma pertinente RFC 7231 , que sustituye a la anterior RFC2616, da 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 de cliente

 627
Author: deamon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-23 17:50:20
  • 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 la autenticación fallida", sino "403: Sé lo que quieres, pero no lo haré". Esa condición puede o no deberse a la autenticación.
  • Tratando de agregar un duplicado: 409 Conflict ("La solicitud no se pudo completar debido a un conflicto con el estado actual del recurso.")

Usted debe definitivamente dar una explicación más detallada en los encabezados de respuesta y / o cuerpo (por ejemplo, con un encabezado personalizado - X-Status-Reason: Validation failed).

 252
Author: Piskvor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-21 22:51:41

Recomiendo 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 compatible) es inapropiado), y la sintaxis de la entidad de solicitud es correcta (por lo tanto, un código de estado 400 (Solicitud incorrecta) es inapropiado), pero no pudo procesar las instrucciones contenidas. Por ejemplo, este error la condición puede ocurrir si un cuerpo de solicitud XML contiene instrucciones XML bien formadas (es decir, sintácticamente correctas), pero semánticamente erróneas.

 171
Author: Julian Reschke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-10 09:25:23

200,300, 400, 500 son todos muy genéricos. Si quieres genérico, 400 está bien.

422 es utilizado por un número creciente de APIs, e incluso es utilizado 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 en '400 + estado de texto' como demasiado genérico. Además, no está aprovechando un analizador preparado para JSON; en contraste, un 422 con una respuesta JSON es muy explícito, y una gran cantidad de información de error puede ser transportado.

Hablando de respuesta JSON, tiendo a estandarizar la respuesta de error 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 soportar en términos de 'riqueza de informes de errores'. Si su estructura de errores es esta, es probable que maneje todas sus necesidades de informes de errores.

 70
Author: sethcall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-02 22:23:59

Un duplicado en la base de datos debe ser un 409 CONFLICT.

Recomiendo usar 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 /

 28
Author: Phil Parker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-16 23:05:13

200

Ugh... (309, 400, 403, 409, 415, 422)... muchas respuestas intentan adivinar, argumentar y estandarizar cuál es el mejor código de retorno para una solicitud http exitosa pero una llamada rest 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 el propio HTTP Request. Se hace una llamada de DESCANSO usando una solicitud de Protocolo de transferencia de Hipertexto y funciona a un nivel más bajo que el método REST invocado en sí. REST es un concepto / enfoque, y su salida es un resultado business/logical , mientras que el código de resultado HTTP es un transport .

Por ejemplo, devolver "404 Not found" cuando llamas a / users / es confuso, porque puede significar:

  • URI es incorrecto (HTTP)
  • No se encuentran usuarios (REST)

" 403 Prohibido/Acceso Denegado " mayo media:

  • Se necesita un permiso especial. Los navegadores pueden manejarlo preguntando al usuario / contraseña. (HTTP)
  • Permisos de acceso incorrectos configurados en el servidor. (HTTP)
  • Necesita ser autenticado (REST)

Y la lista puede continuar con 'Error de servidor 500" (un error HTTP lanzado de Apache/Nginx o un error de restricción de negocio en REST) u otros errores HTTP, etc...

Desde el código, es difícil entender cuál fue la razón del fallo, un HTTP (transporte) fallo o fallo de REPOSO (lógico).

Si la solicitud HTTP físicamente se realizó con éxito, siempre devolverá 200 código, independientemente de que se encuentren o no los registros. Porque el recurso URI es encontrado 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 http, ¿verdad?

En lugar de esto, puede devolver código HTTP 200 con algunas opciones:

  • objeto "error" en JSON resultado si algo sale mal
  • Matriz/objeto JSON vacía si no se encuentra ningún registro
  • Un indicador de resultado/éxito bool en combinación con 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 sus datos no se encuentran, pero es algo malo a nivel de transporte.

De Wiki:

En julio de 2004, el proveedor de telecomunicaciones británico BT Group desplegó el Cleanfeed sistema de bloqueo de contenido, que devuelve un error 404 a cualquier solicitud de contenido identificado como potencialmente ilegal por Internet Watch Fundación. Otros ISP devuelven un error HTTP 403 "prohibido" en el mismo circunstancia. La práctica de emplear falsos errores 404 como un medio para también se ha denunciado la censura encubierta 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 falsos errores 404 y creado un personaje imaginario llamado "Ammar 404" que representa " lo invisible censura".

¿Por qué no responder simplemente 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 geocodificación, incluso si la solicitud falla lógicamente: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

 10
Author: Marcodor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-29 06:09:37

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 opción más obvia a 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 como un error, un código de estado de respuesta de 304 No Modified y Content-Location encabezado identificando el recurso existente sería igual de válido. Cuando la intención es simplemente asegurar que existe un recurso, una solicitud duplicada no sería un error sino una confirmación. La solicitud no es incorrecta, sino simplemente redundante, y el cliente puede hacer referencia 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.

 6
Author: Suncat2000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-17 19:53:47

El adaptador ActiveRecord de Ember-Data espera que 422 UNPROCESSABLE ENTITY sea devuelto por el servidor. Por lo tanto, si eres cliente está escrito en brasa.js deberías usar 422. Sólo entonces DS.Los errores se rellenarán con errores devueltos. Por supuesto, puede cambiar 422 a cualquier otro código en su adaptador.

 6
Author: Daniel Kmak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-03 22:17:18