Tengo un punto final de API que devuelve algunas estadísticas. Actualmente la respuesta se ve así:
Opción 1:
{
"stats": [
{
"name": "some-stats-key1",
"value": 10
},
{
"name": "some-stats-key2",
"value": 20
}
],
... other keys
}
Pero esto parece un poco complejo y sé cómo hacerlo:
Opcion 2:
{
"stats": {
"some-stats-key1": 10,
"some-stats-key2": 20
}
... other keys
}
Entiendo que la Opción 1 es más fácil de extender, pero menos cómoda para los usuarios. ¿Qué otros problemas puedo enfrentar usando una de estas opciones? ¿O debería hacer una solución híbrida como:
Opcion 3:
{
"stats": {
"some-stats-key1": {
"name": "some-stats-key1",
"value": 10
},
"some-stats-key2": {
"name": "some-stats-key2",
"value": 20
},
},
... other keys
}
Las claves "some-stats-key1" y "some-stats-key2" son solo valores internos y se espera que el usuario de la API los asigne a nombres legibles utilizando la documentación. Todas las llaves son únicas.
El orden de las "estadísticas" no es importante.
El caso de uso típico es solo obtener todas las estadísticas, hacer coincidir las claves con nombres legibles y mostrarlas como una tabla en una página web. Pero actualmente no puedo decir si nadie necesitará solo una parte de las estadísticas más adelante.
¿Existe una mejor práctica para este problema?
Array.forEach
y otrasArray
funciones. Sus otros ejemplos agregarán complejidad adicional a las operaciones de tipo matriz, lo que podría estar dificultando la vida de sus clientesRespuestas:
Iría por la opción 2. Si el consumidor de API se convertirá
some-stats-key1
en algo legible, eso probablemente significa que él / ella tiene una lista de valores en los que está interesado (digamos,some-stats-key1
ysome-stats-key3
), e iterará sobre esa lista. Al elegir un objeto JSON, se deserializará como un diccionario / mapa que proporciona una búsqueda conveniente para el consumidor de la API.Esto será más engorroso con la opción 1, donde el consumidor necesita iterar sobre la matriz JSON o crear previamente su propio diccionario con claves interesantes.
La opción 3 es demasiado detallada para mí, la duplicación de los nombres clave simplemente no me atrae.
Si la extensibilidad es una preocupación, siempre puede publicar una v2 de su API que devuelva algo como
y mantenga el v1 para compatibilidad con versiones anteriores. Mantener la compatibilidad con versiones anteriores dentro de una única versión de la API puede ser un verdadero PITA si no tiene un control completo sobre cómo se consume la API. He visto un consumo de una 'ruptura' de API mía cuando acabo de agregar un par clave-valor adicional (opcional) (es decir, sin cambiar la estructura).
fuente
Las dos opciones tienen las ventajas clásicas de List vs. Map.
1) La Lista permite entradas duplicadas y mantiene el orden. Si estas características son importantes, use la Lista, aunque sea más complicada.
2) El mapa no permite duplicados. Mantener el orden es posible con un poco de trabajo extra. La gran ventaja es una mayor simplicidad en el formato de datos, y la búsqueda de un elemento en particular es trivial.
Mi opción predeterminada es siempre el Mapa más simple, pero YMMV.
fuente
Cuando obtengo datos de una API, siempre verifico que todo esté como lo esperaba. Por lo tanto, mi esfuerzo para procesar sus datos consiste en la verificación y el procesamiento real.
En el caso 1 tengo que verificar: a. Hay una matriz si. Todos los elementos de la matriz son diccionarios. C. Cada diccionario tiene una clave "nombre". re. Todos los valores para la clave "nombre" son únicos.
En el caso 3 tengo que verificar: a. Hay un diccionario si. Todos los valores en el diccionario son diccionarios. C. Cada diccionario tiene un "nombre" clave con un valor que coincide con la clave en el diccionario externo. Ligeramente mejor.
En el caso 2 tengo que verificar: a. Hay un diccionario
(Por supuesto, también tengo que verificar los valores). Por lo tanto, su caso 2 requiere la menor cantidad de control de mi parte. De hecho, obtengo una estructura de datos que se puede usar de inmediato.
El único problema con 2 es que no es extensible. Por lo tanto, en lugar de enviar el valor como un número, puede enviar {valor: 10} que luego se puede extender de una manera compatible con versiones anteriores.
La redundancia es mala. Lo único que logra la redundancia es hacerme escribir más código y obligarme a pensar qué debo hacer si los bits redundantes no están de acuerdo. La versión 2 no tiene redundancia.
fuente
Como solicitó buenas prácticas para el diseño de API:
Entonces, dadas las estructuras que ha propuesto, la estructura que implementaría sería similar a esta
fuente
re:overly complex
me parece muy simple. Sigo el punto 1 porque hace que toda la lógica de serialización mantenga convenciones consistentes. El número de elementos en un conjunto de respuestas es un detalle de implementación de la interfaz de servicio. Para comunicar "3" elementos en un conjunto, esos tres elementos se envuelven más convenientemente en una matriz. "1" es un número.re: example from a well known web API
google.comre: example from a framework
todo lo que habla ANSI SQL