¿Cuál es el código de respuesta REST adecuado para una solicitud válida pero un dato vacío?


Por ejemplo, ejecuta una solicitud GET para users/9 pero no hay ningún usuario con id #9. Cual es el mejor código de respuesta?

  • 200 OK
  • 202 Aceptadas
  • 204 Sin contenido
  • 400 Solicitud incorrecta
  • 404 No encontrado
Author: Machavity, 2012-07-31

12 answers

TL; DR: Use 404

Ver Este Blog. Lo explica muy bien.

Resumen de los comentarios del blog sobre 204:

  1. 204 No Content no es terriblemente útil como un código de respuesta para un navegador (aunque de acuerdo con las especificaciones HTTP, los navegadores necesitan entenderlo como un código de respuesta "no cambie la vista").
  2. 204 No Content es sin embargo, muy útil para los servicios web ajax que pueden querer indicar el éxito sin tener que devolver algo. (Especialmente en casos como DELETE o POST s que no requieren retroalimentación).

La respuesta, por lo tanto, a su pregunta es usar 404 en su caso. 204 es un código de respuesta especializado que no debe volver a menudo a un navegador en respuesta a un GET.

Los otros códigos de respuesta que son incluso menos apropiados que 204 y 404:

  1. 200 debe devolverse con el cuerpo de lo que haya obtenido con éxito. No es apropiado cuando la entidad que eres ir a buscar no existe.
  2. 202 se usa cuando el servidor ha comenzado a trabajar en un objeto pero el objeto no está completamente listo todavía. Ciertamente no es el caso aquí. No ha comenzado, ni comenzará, la construcción del usuario 9 en respuesta a una solicitud GET. Eso rompe todo tipo de reglas.
  3. 400 se usa en respuesta a una solicitud HTTP mal formateada (por ejemplo, cabeceras http malformadas, segmentos incorrectamente ordenados, etc.). Esto casi seguramente será manejado por cualquier marco que estás usando. No debería tener que lidiar con esto a menos que esté escribiendo su propio servidor desde cero. Editar: Los nuevos RFC ahora permiten el uso de 400 para solicitudes semánticamente inválidas.

La descripción de Wikipedia de los códigos de estado HTTP son particularmente útiles. También puede ver las definiciones en el documento HTTP / 1.1 RFC2616 en www.w3.org

 154
Author: Crisfole,
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-09-11 17:32:25

Me opongo firmemente a 404 a favor de 204 o 200 con datos vacíos.

La solicitud se recibió y se procesó correctamente: activó el código de la aplicación en el servidor, por lo que realmente no se puede decir que fue un error del cliente y, por lo tanto, toda la clase de códigos de error del cliente (4xx) no es adecuada.

Más importante aún, 404 puede suceder por una serie de razones técnicas. Por ejemplo, la aplicación se desactiva o desinstala temporalmente en el servidor, problemas de conexión de proxy y otras cosas. Por lo tanto, el cliente no puede distinguir entre un 404 que significa "conjunto de resultados vacío" y un 404 que significa "el servicio no se puede encontrar, inténtelo de nuevo más tarde".

Esto puede ser fatal: Imagine un servicio de contabilidad en su empresa que enumera todos los empleados que se deben a un bono anual. Desafortunadamente, la única vez que se llama devuelve un 404. ¿Eso significa que nadie debe recibir un bono, o que la aplicación está actualmente inactiva para una nueva implementación?

-> Para aplicaciones que se preocupan por la calidad de sus datos, 404 por lo tanto es más o menos un no-go.

Además, muchos frameworks de cliente responden a un 404 lanzando una excepción sin hacer más preguntas. Esto obliga al desarrollador del cliente a capturar esa excepción, evaluarla y luego decidir en función de eso si registrarla como un error que es detectado por, por ejemplo, un componente de monitoreo o si ignorarla. Eso tampoco me parece bonito.

La única ventaja de 404 sobre 204 es que puede devolver una entidad de respuesta que puede contener alguna información sobre por qué no se encontró el recurso solicitado. Pero si eso realmente es relevante, entonces uno también puede considerar el uso de una respuesta de 200 OK y diseñar el sistema de una manera que permita respuestas de error en los datos de carga útil. Alternativamente, se podría utilizar la carga útil de la respuesta 404 para devolver información estructurada a la persona que llama. Si recibe, por ejemplo, una página html en lugar de XML o JSON que puede analizar, entonces eso es una buena indicador de que algo técnico salió mal en lugar de una respuesta" sin resultado " que puede ser válida desde el punto de vista de la persona que llama. O uno podría usar un encabezado de respuesta HTTP para eso.

Sin embargo, preferiría un 204 o 200 con respuesta vacía. De esta manera, el estado de la ejecución técnica de la solicitud se separa del resultado lógico de la solicitud. 2xx significa "ejecución técnica ok, este es el resultado, tratar con él".

Creo que en la mayoría de los casos debe dejarse a la cliente para decidir si un resultado vacío es aceptable o no. Al devolver 404 a pesar de una correcta ejecución técnica, el cliente puede decidir considerar los casos como errores que simplemente no son errores.

Otra analogía rápida: Devolver 404 para "no result found" es como lanzar una DatabaseConnectionException si una consulta SQL no devuelve resultados. Puede hacer el trabajo, pero hay muchas causas técnicas posibles que lanzan la misma excepción que luego se confundiría con una válida resultado.

 211
Author: Jens Wurm,
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-11-17 10:29:19

Si se espera que el recurso exista, pero podría estar vacío, yo diría que podría ser más fácil obtener un 200 OK con una representación que indica que la cosa está vacía.

Así que prefiero que /things devuelva un 200 OK con {"Items": []} que un 204 sin nada en absoluto, porque de esta manera una colección con 0 items puede ser tratada de la misma manera que una colección con uno o más items en ella.

Simplemente dejaría el 204 Sin contenido para PUTs y DELETEs, donde podría ser el caso de que realmente no hay representación útil.

En el caso de que /thing/9 realmente no exista, un 404 es apropiado.

 16
Author: j0057,
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-07-22 20:00:30

En proyectos anteriores, he usado 404. Si no hay ningún usuario 9, entonces el objeto no fue encontrado. Por lo tanto 404 No encontrado es apropiado.

Para el objeto existe, pero no hay datos, 204 Ningún Contenido sería apropiado. Creo que en su caso, el objeto no existe .

 14
Author: Max,
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-07-31 18:47:50

Al principio, pensé que un 204 tendría sentido, pero después de las discusiones, creo que 404 es la única respuesta correcta. Considere los siguientes datos:

Usuarios: Juan, Pedro

METHOD  URL                      STATUS  RESPONSE
GET     /users                   200     [John, Peter]
GET     /users/john              200     John
GET     /users/kyle              404     Not found
GET     /users?name=kyle`        200     []
DELETE  /users/john              204     No Content

Algunos antecedentes:

  1. La búsqueda devuelve una matriz, simplemente no tenía ninguna coincidencia, pero tiene contenido: un array vacío.

  2. 404 por supuesto, es mejor conocido por las url que no son compatibles con el servidor solicitado, pero un recurso que falta es de hecho lo mismo.
    Aunque /users/:name está emparejado con users/kyle, el usuario Kyle no es un recurso disponible, por lo que un 404 todavía se aplica. No es un consulta de búsqueda, es una referencia directa por una url dinámica, por lo que es 404.

De todos modos, mis dos centavos :)

 11
Author: Justus Romijn,
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-07-30 06:32:39

De acuerdo con w3 post,

200 OK

La solicitud ha tenido éxito. La información devuelta con la respuesta depende del método utilizado en la solicitud

202 Aceptada

La solicitud ha sido aceptada para su procesamiento, pero el procesamiento no se ha completado.

204 Sin contenido

El servidor ha completado la solicitud pero no necesita devolver un entity-body, y podría querer devolver metainformación actualizada.

400 Solicitud Incorrecta

El servidor no pudo entender la solicitud debido a una sintaxis mal formada. El cliente NO DEBE repetir la solicitud sin modificaciones

401 No autorizado

La solicitud requiere autenticación de usuario. La respuesta DEBE incluir un campo de encabezado WWW-Authenticate

404 No encontrado

El el servidor no ha encontrado nada que coincida con el URI de solicitud. No se indica si la afección es temporal o permanente

 9
Author: Dev4World,
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-03-28 13:21:47

Para resumir o simplificar,

2xx: Datos opcionales: URI bien formado: Criteria no es parte de URI: Si el criterio es opcional que se puede especificar en @RequestBody y @RequestParam debe conducir a 2xx. Ejemplo: filtrar por nombre / estado

4xx: Datos esperados : No está bien formado URI : Criteria es parte de URI : Si el criterio es obligatorio que solo se puede especificar en @PathVariable entonces debería conducir a 4xx. Ejemplo: búsqueda por id único.

Así para el pedido situación: "usuarios / 9" sería 4xx (posiblemente 404) Pero para " usuarios?nombre = superman " debe ser 2xx (posiblemente 204)

 8
Author: Ashish Singh,
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
2016-11-15 18:47:04

Se hacen dos preguntas. Uno en el título y otro en el ejemplo. Creo que esto ha llevado en parte a la cantidad de disputa sobre qué respuesta es apropiada.

El título de la pregunta pregunta acerca de los datos vacíos. Los datos vacíos siguen siendo datos, pero no es lo mismo que no hay datos. Así que esto sugiere solicitar un conjunto de resultados, es decir, una lista, tal vez de /users. Si una lista está vacía, sigue siendo una lista, por lo tanto, un 204 (Sin contenido) es el más apropiado. Usted acaba de pedir una lista de usuarios y ha sido siempre con uno, resulta que no tiene contenido.

El ejemplo proporcionado en su lugar pregunta acerca de un objeto específico, un usuario, /users/9. Si no se encuentra el usuario #9, entonces no se devuelve ningún objeto de usuario. Usted pidió un recurso específico (un objeto de usuario) y no se le dio porque no se encontró, por lo que un 404 es apropiado.

Creo que la forma de resolver esto es si puede usar la respuesta de la manera que esperaría sin agregar ninguna instrucción condicional, luego use un 204 de lo contrario use un 404.

En mis ejemplos puedo iterar sobre una lista vacía sin verificar si tiene contenido, pero no puedo mostrar datos de objetos de usuario en un objeto nulo sin romper algo o agregar una comprobación para ver si es nulo.

Por supuesto, podría devolver un objeto usando el patrón de objeto nulo si eso se adapta a sus necesidades, pero eso es una discusión para otro hilo.

 5
Author: Bluebox,
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-08-01 16:37:03

204 es más apropiado. Especialmente cuando tiene un sistema de alertas para garantizar que su sitio web sea seguro, 404 en este caso causaría confusión porque no sabe que algunas alertas 404 son errores de backend o solicitudes normales, pero la respuesta está vacía.

 2
Author: 刘武豪,
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-01-10 02:59:59

Yo diría que ninguno es realmente apropiado. Como se ha dicho, por ejemplo, por @anneb, yo también creo que parte de los problemas surgen del uso de un código de respuesta HTTP para transportar un estado relacionado con un servicio RESTful. Todo lo que el servicio REST tenga que decir sobre su propio procesamiento debe transportarse por medio de códigos específicos de REST.

1

Yo diría que, si el servidor HTTP encuentra cualquier servicio que está listo para responder a una solicitud que se envió, no debe responder con un HTTP 404 - al final, algo fue encontrado por el servidor-a menos que se lo dijera explícitamente el servicio que procesa la solicitud.

Supongamos por un momento la siguiente URL: http://example.com/service/return/test.

  • El caso A es que el servidor está "simplemente buscando el archivo en el sistema de archivos". Si no está presente, 404 es correcto. Lo mismo es cierto, si le pide a algún tipo de servicio que entregue exactamente este archivo y ese servicio le dice que no existe nada de ese nombre.
  • En el caso B, el el servidor no funciona con archivos "reales", pero en realidad la solicitud es procesada por algún otro servicio, por ejemplo, algún tipo de sistema de plantillas. Aquí, el servidor no puede hacer ninguna reclamación sobre la existencia del recurso, ya que no sabe nada sobre él (a menos que se lo indique el servicio que lo maneja).

Sin ninguna respuesta del servicio que requiera explícitamente un comportamiento diferente, el servidor HTTP solo puede decir 3 cosas:

  • 503 si el servicio que se supone que maneja el la solicitud no se está ejecutando o respondiendo;
  • 200 de lo contrario, ya que el servidor HTTP puede satisfacer la solicitud, sin importar lo que el servicio diga más tarde;
  • 400 o 404 para indicar que no existe tal servicio (a diferencia de "existe pero sin conexión") y no se encontró nada más.

2

Para volver a la pregunta: Creo que el enfoque más limpio sería no utilizar un HTTP ningún código de respuesta en absoluto que no sea dicho antes. Si el servicio es presente y respondiendo, el código HTTP debe ser 200. La respuesta debe contener el estado devuelto por el servicio en un encabezado separado – aquí, el servicio puede decir

  • REST:EMPTY por ejemplo, si se le pidió que buscara sth. y que la investigación volvió vacía;
  • REST:NOT FOUND si se le pidió específicamente para sth. "ID-like" - sea un nombre de archivo o un recurso por ID o entrada No. 24, etc. - y ese recurso específico no se encontró (por lo general, se solicitó un recurso específico y no encontrado);
  • REST:INVALID si alguna parte de la solicitud que se envió no es reconocida por el servicio.

(tenga en cuenta que les puse el prefijo "REST:" a propósito para marcar el hecho de que si bien estos pueden tener los mismos valores o palabras que los códigos de respuesta HTTP, son sth. completamente diferente)

3

Volvamos a la URL anterior e inspeccionemos el caso B donde service indica al servidor HTTP que no maneja esta solicitud por sí mismo, sino que la pasa a SERVICE. HTTP solo sirve lo que es devuelto por SERVICE, no sabe nada sobre la porción return/test ya que es manejada por SERVICE. Si ese servicio se está ejecutando, HTTP debería devolver 200 ya que encontró algo para manejar la solicitud.

El estado devuelto por SERVICE (y que, como se dijo anteriormente, le gustaría ver en un encabezado separado) depende de qué acción se espera realmente:

  • si return/test pide un recurso específico: si existe, devolverlo con un estado de REST:FOUND; si ese recurso no existe, devolver REST:NOT FOUND; esto podría extenderse a devolver REST:GONE si sabemos que una vez existió y no volverá, y REST:MOVED si sabemos que se ha ido a hollywood{[38]]}
  • si return/test se considera una operación de búsqueda o filtro: si el conjunto de resultados está vacío, devuelve un conjunto vacío en el tipo solicitado y un estado de REST:EMPTY; un conjunto de resultados en el tipo solicitado y un estado de REST:SUCCESS
  • si return/test no es una operación recogida por SERVICE: devuelve REST:ERROR si es completamente incorrecto (por ejemplo, un error tipográfico como retrun/test), o REST:NOT IMPLEMENTED en caso de que esté planeado para más tarde.

4

Esta distinción es mucho más limpia que mezclar las dos cosas diferentes. También hará que la depuración sea más fácil y el procesamiento solo un poco más complejo, si es que lo es.

  • Si se devuelve un HTTP 404, el servidor me dice, "No tengo idea de lo que estás hablando". Mientras que el RESTO de mi solicitud podría estar perectamente bien, estoy buscando a Par'Machh en todos los lugares equivocados.
  • Por otro lado, HTTP 200 y REST:ERR me dicen que obtuve el servicio pero hice algo mal en mi solicitud al servicio.
  • Desde HTTP 200 y REST:VACÍO, sé que no hice nada malo – servidor correcto, el servidor encontró el servicio, solicitud correcta al servicio – pero el resultado de la búsqueda está vacío.

Resumen

El problema y la discusión surgen del hecho de que los códigos de respuesta HTTP se están utilizando para denota el estado de un servicio cuyos resultados son servidos por HTTP, o para denotar sth. eso no está en el ámbito del propio servidor HTTP. Debido a esta discrepancia, la pregunta no puede ser respondida y todas las opiniones están sujetas a mucha discusión.

El estado de una solicitud procesada por un servicio y no por el servidor HTTP REALMENTE NO DEBERÍA (RFC 6919) ser dado por un código de respuesta HTTP. El código HTTP (RFC 2119) solo debe contener información que el servidor HTTP puede dar desde su propio ámbito: es decir, si se determinó que el servicio procesaba la solicitud o no.

En su lugar, se debe usar una forma diferente para informar al consumidor sobre el estado de la solicitud al servicio que realmente está procesando la solicitud. Mi propuesta es hacerlo a través de un encabezado específico. Idealmente, tanto el nombre del encabezado como su contenido siguen un estándar que facilita a los consumidores trabajar con estas respuestas.

 1
Author: dariok,
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-06-15 15:56:49

Codifica el contenido de la respuesta con una enumeración común que permite al cliente activarla y bifurcar la lógica en consecuencia. No estoy seguro de cómo su cliente distinguiría la diferencia entre un "data not found" 404 y un "web resource not found" 404? No desea que alguien navegue a user Z/9 y que el cliente se pregunte como si la solicitud fuera válida pero no se devolvieran datos.

 0
Author: ComeIn,
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
2016-07-25 16:23:35

¿Por qué no usar 410? Sugiere que el recurso solicitado ya no existe y se espera que el cliente nunca realice una solicitud para ese recurso, en su caso users/9.

Puede encontrar más detalles sobre 410 aquí: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

 -1
Author: Akshat Shah,
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
2016-11-30 03:58:17