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


Estoy construyendo 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 donde una solicitud intenta agregar un duplicado en mi base de datos?

He revisado 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?


653
2017-07-20 13:03


origen


Respuestas:


Para la falla de validación de entrada: 400 Petición Incorrecta + tu descripción opcional. Esto se sugiere en el libro "Servicios web RESTful". Para doble envío: 409 Conflicto


Actualización de junio de 2014

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

La solicitud no pudo ser entendida por el servidor debido a una sintaxis mal formada

Por lo que podría se ha argumentado que era inapropiado para errores semánticos. Pero ya no más; desde junio de 2014, la norma pertinente RFC 7231, que reemplaza al anterior RFC2616, da el uso de 400 Petición 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


618
2017-07-20 13:05



  • Error de validación: 403 Forbidden ("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 haré eso". Esa condición puede o no deberse a la autenticación.
  • Intentando agregar un duplicado: 409 Conflicto ("La solicitud no pudo completarse debido a un conflicto con el estado actual del recurso").

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


249
2017-07-20 13:24



yo 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 admitido) es inapropiado) y la sintaxis de la entidad de solicitud es correcta (por lo tanto, 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.


167
2017-07-20 14:56



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 API, e incluso es utilizado por Rails fuera de la caja.

No importa qué código de estado elijas para tu API, alguien estará en desacuerdo. Pero prefiero 422 porque pienso en '400 + texto' como demasiado genérico. Además, no está aprovechando un analizador listo para JSON; en contraste, un 422 con una respuesta JSON es muy explícito, y se puede transmitir una gran cantidad de información de error.

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


69
2018-04-04 17:40



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/


27
2017-10-16 23:05



200

Ugh ... (309, 400, 403, 409, 415, 422) ... muchas respuestas tratando de adivinar, argumentar y estandarizar cuál es el mejor código de retorno para un solicitud http exitosa pero una llamada de descanso fallida.

Es incorrecto para mezclar códigos de protocolo HTTP y resultados REST.

Sin embargo, vi muchas implementaciones mezclándolos, y muchos desarrolladores pueden no estar de acuerdo conmigo.

Los códigos de retorno HTTP están relacionados con HTTP Request sí mismo. Una llamada REST se realiza utilizando una solicitud de Protocolo de transferencia de hipertexto y funciona en un nivel inferior al método REST invocado en sí. REST es un concepto / enfoque, y su resultado es un negocio / lógico resultado, mientras que el código de resultado HTTP es transporte uno.

Por ejemplo, devolver "404 No encontrado" cuando llama a / users / confunde, porque puede significar:

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

"403 prohibido / acceso denegado" puede significar:

  • Permiso especial necesario. Los navegadores pueden manejarlo preguntando al usuario / contraseña. (HTTP)
  • Permisos de acceso incorrectos configurados en el servidor. (HTTP)
  • Necesita estar autenticado (REST)

Y la lista puede continuar con 'Error del servidor 500' (un error HTTP arrojado por Apache / Nginx o un error de restricción empresarial en REST) ​​u otros errores HTTP, etc.

Desde el código, es difícil entender cuál fue el motivo del error, una falla HTTP (transporte) o una falla REST (lógica).

Si la solicitud HTTP se realizó físicamente correctamente, debería siempre código de retorno 200, independientemente de los registros encontrados o no. Porque el recurso de URI es encontró 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, correcto?

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

  • Objeto "error" en el resultado de JSON si algo sale mal
  • Matriz / objeto JSON vacío si no se encuentra ningún registro
  • Un indicador de resultado / éxito de 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 incorrecto en el nivel de transporte.

De Wiki:

En julio de 2004, el proveedor de telecomunicaciones del Reino Unido 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 "prohibido" HTTP 403 en el mismo   circunstancias. La práctica de emplear errores falsos 404 como medio para   ocultar la censura también se ha informado en Tailandia y Túnez. En   Túnez, donde la censura fue severa antes de la revolución de 2011,   la gente se dio cuenta de la naturaleza de los falsos errores 404 y creó   un personaje imaginario llamado "Ammar 404" que representa "lo invisible   censurar".

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


7
2017-09-23 12:42



Código de estado 304 no modificado también haría una respuesta aceptable a una solicitud duplicada. Esto es similar al procesamiento de 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 como un error, un código de estado de respuesta de 304 No modificado y Content-Location el encabezado que identifica el recurso existente sería igual de válido. Cuando la intención es simplemente asegurar que exista un recurso, una solicitud duplicada no sería un error sino una confirmación. La solicitud no es incorrecta, pero es simplemente redundante, y el cliente puede consultar el recurso existente.

En otras palabras, la solicitud es buena, pero dado que el recurso ya existe, el servidor no necesita realizar ningún procesamiento adicional.


6
2018-03-17 19:14



El adaptador ActiveRecord de Ember-Data espera 422 UNPROCESSABLE ENTITY para ser devuelto desde el servidor. Por lo tanto, si su cliente está escrito en Ember.js, debe usar 422. Solo entonces DS.Errors se completará con los errores devueltos. Por supuesto, puede cambiar 422 a cualquier otro código en tu adaptador.


6
2017-12-03 22:17