¿Cuál es el código de respuesta REST adecuado para una solicitud válida pero una información vacía?

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

  • 200 OK
  • 202 Aceptado
  • 204 Sin contenido
  • 400 Petición Incorrecta
  • 404 No encontrado

TL; DR: Use 404

Ver este blog Lo explica muy bien.

Resumen de los comentarios del blog en 204 :

  1. 204 No Content no es terriblemente útil como código de respuesta para un navegador (aunque de acuerdo con la especificación HTTP, los navegadores deben entenderlo como un código de respuesta “no cambiar la vista”).
  2. 204 No Content embargo, el 204 No Content es 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 comentarios).

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 son aún menos apropiados que 204 y 404 .

  1. 200 debe devolverse con el cuerpo de lo que sea que haya obtenido con éxito. No es apropiado cuando la entidad que está buscando no existe.
  2. 202 se usa cuando el servidor ha comenzado a trabajar en un objeto, pero el objeto aún no está listo. 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 utiliza en respuesta a una solicitud HTTP mal formateada (por ejemplo, encabezados http mal formados, segmentos ordenados incorrectamente, etc.). Esto seguramente será manejado por cualquier marco que esté usando. No deberías tener que lidiar con esto a menos que estés escribiendo tu propio servidor desde cero. Editar : Las RFC más nuevas ahora permiten que 400 se use para solicitudes semánticamente inválidas.

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

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 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 ocurrir por una serie de razones técnicas. Por ejemplo, la aplicación que se desactivó o desinstaló 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 más tarde”.

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

-> Para las aplicaciones que se preocupan por la calidad de sus datos, 404 por lo tanto es casi un no-go.

Además, muchos frameworks de clientes responden a un 404 lanzando una excepción sin más preguntas. Esto obliga al desarrollador del cliente a atrapar esa excepción, evaluarla y luego decidir en función de si registrarla como un error recogido, por ejemplo, por un componente de supervisión o ignorarlo. Eso tampoco me parece bonito.

La única ventaja de 404 sobre 204 es que puede devolver una entidad de respuesta que puede contener cierta información sobre por qué no se encontró el recurso solicitado. Pero si eso es realmente relevante, entonces uno también puede considerar usar una respuesta 200 OK y diseñar el sistema de una manera que permita respuestas de error en los datos de la carga útil. Alternativamente, uno podría usar 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 ese es un buen 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.

Aún así, preferiría un 204 o 200 con respuesta vacía. De esta forma, 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 bien, este es el resultado, lidiar con eso”.

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

Otra analogía rápida: devolver 404 para “no se encontró ningún resultado” es como lanzar una excepción DatabaseConnectionException si una consulta SQL no arrojó resultados. Puede hacer el trabajo, pero hay muchas causas técnicas posibles que arrojan la misma excepción que luego se confundiría con un resultado válido.

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 indique que el objeto está vacío.

Así que prefiero que / cosas devuelvan un 200 OK con {“Items”: []} que un 204 sin nada, porque de esta manera una colección con 0 elementos se puede tratar igual que una colección con uno o más artículo en él.

Simplemente dejaría el 204 Sin contenido para PUT y DELETE, donde podría darse el caso de que realmente no haya una representación útil.

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

En proyectos anteriores, he usado 404. Si no hay usuario 9, entonces no se encontró el objeto. Por lo tanto, 404 Not Found es apropiado.

Para el objeto existe, pero no hay datos, 204 Ningún contenido sería apropiado. Creo que en tu caso, el objeto no existe sin embargo.

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

Usuarios: John, Peter

 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 tiene ninguna coincidencia pero tiene contenido: una matriz vacía .

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

De todos modos, mis dos centavos 🙂

De acuerdo con la publicación w3 ,

200 OK

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

202 Aceptado

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

204 Sin contenido

El servidor ha cumplido la solicitud pero no necesita devolver un cuerpo de entidad, y puede querer devolver metainformación actualizada.

400 Petición Incorrecta

La solicitud no pudo ser entendida por el servidor debido a una syntax 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 servidor no ha encontrado nada que coincida con el URI de solicitud. No se indica si la condición es temporal o permanente

Para resumir o simplificar,

2xx: datos opcionales: URI bien formado: los criterios no son parte del URI: si el criterio es opcional, se puede especificar en @RequestBody y @RequestParam debe conducir a 2xx. Ejemplo: filtrar por nombre / estado

4xx: Datos esperados: URI no bien formado: los criterios son parte del URI: si el criterio es obligatorio y solo se puede especificar en @PathVariable, debe conducir a 4xx. Ejemplo: búsqueda por ID único.

Por lo tanto, para la situación solicitada: “users / 9” sería 4xx (posiblemente 404) pero para “users? Name = superman” debería ser 2xx (posiblemente 204)

Hay dos preguntas hechas. Uno en el título y uno en el ejemplo. Creo que esto ha conducido en parte a la cantidad de disputas sobre qué respuesta es apropiada.

El título de pregunta pregunta sobre datos vacíos. Los datos vacíos siguen siendo datos, pero no son lo mismo que no hay datos. Entonces, 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, una 204 (Sin contenido) es la más adecuada. Usted acaba de solicitar una lista de usuarios y se le ha proporcionado uno, simplemente no tiene contenido.

El ejemplo proporcionado en su lugar pregunta sobre un objeto específico, un usuario, /users/9 . Si el usuario n. ° 9 no se encuentra, entonces no se devuelve ningún objeto de usuario. 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 ningún enunciado 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 los datos del objeto del usuario en un objeto nulo sin romper algo o agregar un cheque para ver si es nulo.

Por supuesto, puede devolver un objeto utilizando el patrón de objeto nulo si eso satisface sus necesidades, pero esa es una discusión para otro hilo.

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

Yo diría que ninguno de los dos es realmente apropiado. Como se ha dicho, por ejemplo, @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. Cualquier cosa que el servicio REST tenga que decir sobre su propio procesamiento debe ser transportada por medio de códigos específicos REST.

1

Argumentaría que, si el servidor HTTP encuentra que algún servicio está listo para responder a una solicitud, se envió, no debería responder con un HTTP 404; al final, el servidor encontró algo, a menos que así lo indique 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 “simplemente busca 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 servidor no funciona con archivos “reales”, pero en realidad la solicitud es procesada por otro servicio, por ejemplo, algún tipo de sistema de plantillas. Aquí, el servidor no puede hacer ningún reclamo sobre la existencia del recurso ya que no sabe nada al respecto (a menos que el servicio lo indique).

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

  • 503 si el servicio que se supone que maneja la solicitud no se está ejecutando o respondiendo;
  • 200 contrario, como el servidor HTTP puede satisfacer la solicitud, sin importar lo que diga el servicio más tarde;
  • 400 o 404 para indicar que no existe dicho servicio (a diferencia de “existe pero fuera de línea”) y no se encontró nada más.

2

Para volver a la pregunta que nos ocupa: creo que el enfoque más limpio sería no utilizar un código de respuesta HTTP en absoluto más allá de lo dicho anteriormente. Si el servicio está presente y responde, el código HTTP debe ser 200. La respuesta debe contener el estado del servicio devuelto en un encabezado separado; aquí, el servicio puede decir

  • REST:EMPTY por ejemplo, si se le solicitó que buscara algo. y esa investigación volvió vacía;
  • REST:NOT FOUND si se lo pidieron específicamente para algo. “ID-like” – sea un nombre de archivo o un recurso por ID o entrada N. ° 24, etc. – y ese recurso específico no se haya encontrado (generalmente, se solicitó y no se encontró un recurso específico);
  • REST:INVALID si el servicio no reconoce ninguna parte de la solicitud que se envió.

(nótese que he prefijado esto con “REST:” a propósito para señalar el hecho de que si bien estos pueden tener los mismos valores o términos que los códigos de respuesta HTTP, son algo completamente diferente)

3

Regresemos a la URL anterior e inspeccionamos el caso B, donde el servicio indica al servidor HTTP que no maneja esta solicitud por sí solo, sino que la pasa a SERVICE . HTTP solo proporciona lo que devuelve SERVICE , no sabe nada sobre la parte de return/test tal como la gestiona SERVICE . Si ese servicio se está ejecutando, HTTP debería devolver 200 ya que de hecho 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 la return/test solicita un recurso específico: si existe, devuélvalo con un estado de REST:FOUND ; si ese recurso no existe, devuelve REST:NOT FOUND ; esto podría extenderse para devolver REST:GONE si sabemos que existió una vez y no regresará, y REST:MOVED si sabemos que se ha ido.
  • si la return/test se considera una operación de búsqueda o similar a un filtro: si el conjunto de resultados está vacío, devuelva 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 la return/test no es una operación reconocida por el SERVICE : devuelva REST:ERROR si está completamente equivocado (por ejemplo, un error tipográfico como retrun/test ), o REST:NOT IMPLEMENTED en caso de que se planee para más adelante.

4

Esta distinción es mucho más limpia que mezclar las dos cosas diferentes. También facilitará la depuración y procesará solo un poco más complejo, si es que lo hace.

  • Si se devuelve un HTTP 404, el servidor me dice: “No tengo idea de lo que estás hablando”. Si bien la parte de DESCANSO de mi solicitud podría ser correcta, estoy buscando par’Mach en todos los lugares equivocados.
  • Por otro lado, HTTP 200 y REST: ERR me dicen que obtuve el servicio pero que hice algo mal en mi solicitud al servicio.
  • Desde HTTP 200 y REST: VACÍO, sé que no hice nada incorrecto: 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 utilizan para denotar el estado de un servicio cuyos resultados son servidos por HTTP, o para denotar algo. eso no está en el scope del servidor HTTP en sí. 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 el servidor HTTP REALMENTE NO DEBERÍA (RFC 6919) ser dado por un código de respuesta HTTP. El código HTTP DEBERÍA (RFC 2119) solo contener información que el servidor HTTP puede dar desde su propio scope: es decir, si el servicio se encontró para procesar la solicitud o no.

En cambio, DEBE usarse una forma diferente para informarle al consumidor sobre el estado de la solicitud al servicio que está procesando realmente la solicitud. Mi propuesta es hacerlo a través de un encabezado específico. Idealmente, tanto el nombre del encabezado como sus contenidos siguen un estándar que facilita a los consumidores trabajar con estas respuestas.

Codifique el contenido de la respuesta con una enumeración común que permita al cliente activarla y lógica de la horquilla en consecuencia. No estoy seguro de cómo su cliente podría distinguir la diferencia entre un 404 “datos no encontrados” 404 y un “recurso web no encontrado” 404? No quiere que alguien busque el usuario Z / 9 y haga que el cliente se pregunte si la solicitud era válida, pero no se devolvió ningún dato.

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

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

    Intereting Posts