Actualmente estoy codificando una API para una red social con Slim Framework. Mi pregunta es: ¿Cuáles son las mejores prácticas cuando no hay filas para devolver en la estructura json?
Digamos que esta llamada / v1 / get / movies devuelve 2 filas de los nombres de películas de la tabla:
[
{"name": "Ghostbusters"},
{"name": "Indiana Jones"}
]
Pero, luego llamo / v1 / get / books y no hay filas en esa tabla. ¿Debo devolver una estructura vacía?
[
]
... o sería mejor un mensaje y un código de error?
[
"errors": {
"message": "no matches found",
"code": 134
}
]
¿Cuál es una mejor práctica? (la API se usará en aplicaciones iOS y Android) ¡Gracias!
programming-practices
rest
api-design
json
Andres SK
fuente
fuente
[{"name": "..."}, {"name":"..."}]
Respuestas:
Por lo general, devolvería el número de registros en resultado como metadatos. No estoy seguro de si es una práctica REST normal, pero no se trata de muchos datos adicionales y es muy precisa. Por lo general, existe una paginación para muchos servicios, no es práctico devolver un gran conjunto de resultados a la vez. Personalmente, me molesta cuando hay paginación para pequeños conjuntos de resultados. Si está vacío, regrese
number_of_records : 0
y reserve como lista / matriz vacíabooks : []
.EDITAR (pocos años después): la respuesta de Martin Wickman es mucho mejor, aquí hay una "breve" explicación de por qué.
Cuando se trata de paginación, siempre tenga en cuenta la posibilidad de que el contenido o el orden cambien. Como, la primera solicitud llega, 24 resultados, usted devuelve primero 10. Después de eso, se inserta "nuevo libro" y ahora tiene 25 resultados, pero con la solicitud original vendría ordenado en el décimo lugar. Cuando el primer usuario solicita la segunda página, no obtendría un "libro nuevo". Hay maneras de manejar tales problemas, como proporcionar "id de solicitud" que debe enviarse con las siguientes llamadas a la API, luego regresar la página siguiente del conjunto de resultados "antiguo", que debe almacenarse de alguna manera y vincularse a "id de solicitud". La alternativa es agregar un campo como "la lista de resultados ha cambiado desde la primera solicitud".
En general, si puede, intente hacer un esfuerzo adicional y evitar la paginación. La paginación es un estado adicional que puede ser mutado y el seguimiento de dichos cambios es propenso a errores, aún más porque tanto el servidor como el cliente necesitan manejarlo.
Si tiene demasiados datos para procesar a la vez , considere devolver la "lista de identificación" con todos los resultados y detalles para algunos fragmentos de esa lista, y proporcione llamadas de API multi_get / get_by_id_list para recursos.
fuente
books
parámetro es un objeto pero 'libros' implica más de uno y más de uno implica una matriz. Los metadatos son geniales y todos, pero en última instancia, esperaría que una colección de libros sea una matriz de objetos de libros; si no hay libros, solo dame la matriz vacíaTu ejemplo está roto. No debería tener objetos json con claves duplicadas. Lo que está buscando es una matriz con objetos de película, como esta:
Este enfoque también responde a su pregunta. Debería devolver una matriz vacía cuando la consulta no coincida:
Por otro lado, si intenta obtener un recurso de película específico
GET api/movie/34
y esa película no existe, devuelva 404 con un mensaje de error adecuado (codificado con json) en el cuerpofuente
json_xs
.Si esto es JSON, realmente debería considerar devolver una matriz de objetos. Esto tiene muchas ventajas, incluyendo que cuando no tienes registros es una matriz vacía.
Entonces, cuando tenga registros, regresaría:
Y cuando no tienes registros, regresarías:
fuente
Si ejecuta la operación con éxito, pero no tiene nada que devolver, como un mapa vacío
{}
o una matriz vacía[]
, preferiría responder con el código de respuesta 204, aquí hay un extracto de la especificación de Definiciones de código de estado HTTP :Esencialmente, recomiendo usar 204 en aplicaciones RESTful sobre HTTP cuando no hay nada que devolver.
fuente
Se ha realizado una cantidad razonable de trabajo en la creación de un formato estandarizado de API JSON .
Seguir los principios de esa especificación significa que todos los recursos devueltos deberían ser efectivamente "colecciones" (incluso cuando se incluye un solo recurso). Seguir esto significaría que su llamada a
/v1/get/movies
volvería:Su llamada a
/v1/get/books
(que devuelve cero recursos) devolvería:fuente
Para su ejemplo específico, recomendaría que / v1 / get / books devuelva HTTP 200 con una matriz vacía.
Si estoy leyendo tu publicación correctamente, tu API tiene la intención de recopilar libros. Metafóricamente hablando, tiene una estantería para libros, un estante de DVD para películas y posiblemente otros contenedores que no ha mencionado aquí. Debido a que tiene la intención de recolectar libros, / v1 / get / books es su estantería. Esto significa que hay un recurso válido allí, una lista de libros, que está vacío en su ejemplo específico.
La razón por la que no sugiero devolver HTTP 404 en este caso es que la estantería todavía está allí. No hay ningún libro en este momento, pero sigue siendo una estantería. Si no fuera una estantería, por ejemplo, si la API no tenía la intención de recolectar libros, entonces HTTP 404 sería apropiado. Pero debido a que hay un recurso allí, no debe indicar que no hay uno, lo que hace HTTP 404. Por lo tanto, sostengo que 200 con una matriz vacía (que significa la colección) es más apropiado.
La razón por la que no sugiero devolver HTTP 204 es que esto sugeriría que "Sin contenido" es el estado normal de las cosas: realizar esta acción en este recurso normalmente no devolvería nada. Es por eso que generalmente se usa como respuesta a las solicitudes DELETE, por ejemplo: la naturaleza de la eliminación generalmente significa que no queda nada para devolver. El caso es similar cuando se usa para responder a solicitudes con la familia de encabezados If-Modified: solo quería contenido si el recurso había cambiado, pero no lo ha hecho, por lo que no le daré ningún contenido.
Pero sostengo que para OBTENER una colección vacía pero válida, HTTP 204 no tiene sentido. Si hubiera elementos en la colección, la representación adecuada sería una matriz de esos datos. Por lo tanto, cuando no hay datos allí (pero la colección es válida), la representación adecuada es una matriz vacía.
fuente
Realmente deberías hacer solo una de dos cosas
O bien Devuelve un
200 (OK)
código de estado y una matriz vacía en el cuerpo.O devuelva un
204 (NO CONTENT)
código de estado y NO cuerpo de respuesta.Para mí, la opción 2 me parece más técnicamente correcta y está en línea con los principios REST y HTTP.
Sin embargo, la opción 1 parece más eficiente para el cliente, porque el cliente no necesita lógica adicional para diferenciar entre dos códigos de estado (exitosos). Como sabe que siempre recibirá una matriz, simplemente tiene que verificar si no tiene ninguno, uno o muchos elementos y procesarlos adecuadamente
fuente
He visto ambos casos en entornos de producción. El que elijas dependerá de quién usará la API. Si quieren saber por qué la lista está vacía o para asegurarse de que la lista está realmente vacía y no se produjeron errores al recuperarla, entonces debe adjuntar un objeto "errores". Si no les importa, vaya devolviendo una lista vacía. Optaría por un segundo enfoque, ya que cubre más necesidades que el primero.
fuente
Lo primero que debe tener en cuenta, ya que está creando una API RESTful, es devolver un código de respuesta apropiado. Y el código de respuesta más apropiado para comunicar que la solicitud se realizó normalmente, pero el recurso solicitado no está disponible en este momento es el venerable 404.
Si diseña su API de tal manera que siempre devuelva un código de respuesta razonable, es posible que ni siquiera necesite devolver un cuerpo cuando no se encontró el recurso. Dicho esto, devolver un cuerpo, especialmente uno legible por humanos, no puede doler.
Aquí no hay "mejores prácticas", sus dos ejemplos son arbitrarios, simplemente elija uno y sea coherente . Los desarrolladores odian las sorpresas, si
/v1/get/movies
regresa{}
cuando no hay películas,/v1/get/actors
también esperaríamos regresar{}
cuando no hay actores.fuente
No creo que la respuesta correcta sea la que está marcada.
La respuesta proporcionada por nirth debería ser la mejor, en un verdadero escenario REST. La respuesta del cuerpo debe estar vacía y el código de estado http: 204; el recurso existe pero no tiene "contenido" en ese momento: está vacío.
REST HTTP_Status_Codes
fuente
Recomiendo más de 200 matrices vacías, ya que simplifica el manejo por parte de todos los clientes de la API. 200+ array significa "Devolví todos los datos que están allí". Tanto para el código que entrega los datos como para el código que los procesa, el número de elementos sería irrelevante.
Todos los demás códigos de estado deben estar debidamente documentados y entregados por el servidor y procesados por el cliente, y todos sabemos la probabilidad de que esto suceda.
Hubo una sugerencia para devolver el estado 204 + cuerpo vacío. Eso significa que se fuerza cada solo cliente al estado del proceso 204 correctamente. ¡Además, los obligas a manejar respuestas que no sean JSON! Espero que todos se den cuenta de que solo porque una solicitud recibió una respuesta, no significa que la respuesta vino del servidor cuando se usa http, y solo una verificación de que la respuesta es JSON maneja muchos de esos casos.
fuente
Yo "depende".
Si cero es un resultado razonable, devuelva la lista vacía. Por ejemplo, si desea obtener todos los empleados llamados "bob" donde "ninguno" es un resultado bastante razonable. Si no es un resultado esperado, devuelve un error. Por ejemplo, obtener una lista histórica de las direcciones de las calles de una persona que usted emplea. Deben vivir en algún lugar, por lo que probablemente ningún resultado sea un error, no solo una condición normal.
Estoy seguro de que puede discutir con los detalles de mi ejemplo, pero tiene la idea ...
fuente
get
en su URL no es RESTful, GET está implícito en el método HTTP.GET
api/movies
return a200 OK
con una matriz vacía[]
.GET
api/movies/1
(donde1
está la identificación) y no existe, devuelva a404 Not Found
.¿Por qué? Estás solicitando recursos . Cuando solicita la colección, el recurso en sí (la colección) existe. Por lo tanto, a
404
está mal. Pero si solicita una película específica y no existe, el recurso solicitado no existe y debe devolver a404
.fuente
Si está devolviendo JSON, es mejor devolver siempre el mensaje de conteo y error y tal vez un booleano que indique si hay error o no, esos son mis tres meta valores estándar devueltos con cada lista de filas.
fuente