¿JSON plano o anidado para datos jerárquicos?

12

He cambiado de ida y vuelta ~ 5 veces ya. Este punto final REST /api/tags/será para uso interno (sin clientes de terceros), soy el único que trabaja con él.

Estoy decidiendo entre estas dos representaciones:

Plano

{  
   "types":[  
      {  
         "id":1,
         "text":"Utility"
      },
      {  
         "id":7,
         "text":"Lease Terms"
      },
   ],
   "tags":[
      {  
         "id":8,
         "text":"Water",
         "type":1
      },
      {  
         "id":9,
         "text":"Electricity",
         "type":1
      },
      {  
         "id":5,
         "text":"Minimum 12 month lease",
         "type":7
      },
      {  
         "id":17,
         "text":"lease negotiable/flexible",
         "type":7
      },
   ]
}
  • Es algo modular. Puede agregar otra capa superior como "país" sin romper la compatibilidad.

Anidado

{  
   "1":{  
      "text":"Utility",
      "tags":{  
         "8":{  
            "text":"Water"
         },
         "9":{  
            "text":"Electricity"
         },
      }
   },
   "2":{  
      "text":"Lease Terms",
      "tags":{  
         "5":{  
            "text":"Minimum 12 month lease"
         },
         "17":{  
            "text":"lease negotiable/flexible"
         },
      }
   },
}
  • Ya está en un formato utilizable. No es necesario recorrer los datos antes de usarlos.
  • Ahorra algo de ancho de banda. Incluso después de gzip, esto es un poco más pequeño.

¿Cuál debería usarse y por qué? Si se trata de una cuestión de preferencia personal, ¿qué representación preferirían los desarrolladores experimentados y por qué?

dvtan
fuente
Is this a matter of personal preference?. Creo que sí. Requisitos> necesidades> preferencias
Laiv
1
@Laiv En ese caso, mi pregunta debería reformularse "¿Qué representación prefieren los desarrolladores experimentados y por qué?"
dvtan
¿Son esta identificación estable a lo largo del tiempo y está bien para que el cliente la recuerde y la use más tarde, o son solo mensajes locales?
Erik Eidt
@ErikEidt Son claves primarias permanentes de la base de datos.
dvtan
¿Considera el agua más como una subclase de utilidad o más como una instancia de utilidad?
Erik Eidt

Respuestas:

8

Depende de su caso de uso.

Cuando se usa JSON con lenguajes mecanografiados estáticos, hay una gran ventaja si su estructura se asigna a sus tipos. Esto significa que todos los nombres de las claves deben conocerse de antemano.

Entonces, si planea usar Java para consumir el servicio, o si planea documentarlo con el esquema JSON, el número uno será mucho más limpio (por supuesto, ambos funcionarán).

fdreger
fuente
4

Difícil de decir sin más contexto. He trabajado con ambos, pero progresivamente comencé a inclinarme al # 1. En general, he encontrado la simplicidad más relevante que la sofisticación.

En el n. ° 1, las entidades y las relaciones son claras y obvias, mientras que el n. ° 2 requiere una forma diferente de pensar. Para algunas personas, los árboles (como estructuras de datos) no son tan autodescriptivos. Piense en desarrolladores junior que apenas han visto una composición | agregación más profunda que Persona> Dirección .

Podría leer # 1 como:

  • Hay una colección de etiquetas mecanografiadas .

Pero, ¿cómo podríamos describir el # 2 solo en 7 palabras? Si no estuviera familiarizado con las estructuras de los árboles, podría leer # 2 como

  • Las etiquetas tienen dos atributos 5 y 17, pero no sé sus tipos. Cualquiera que sea el tipo, tiene un atributo, texto .

No me malinterpreten, el # 2 podría ser una solución inteligente, pero no sacrificaría la legibilidad por la inteligencia (o eficiencia) innecesariamente.

Al escribir esta respuesta, estoy trabajando en un proyecto que debe integrarse con un servicio de terceros cuyas respuestas son muy similares a la n. ° 2. El servicio nos proporciona un calendario: año, meses, días y horas del día.

 { "2017" : { "01": { "01" : ["00:00", "01:00", "02:00"] } } } 

Como desarrollador de Java que soy, la deserialización de la respuesta del servicio terminó en un código que no es legible porque no hay una asignación directa a las clases a través de getters | setters | constructores. En su lugar, he tenido que atravesar el documento ( getNode, getSiblings, getNodeName, getChildAsText, isNodeObject, isText, etc.) y llenar mi jerarquía de clases manualmente. ¡Finalmente, logré mapear el árbol de números en una colección de marcas de tiempo! ¿Qué estructura dirías que es más fácil de leer y deserializar? ¿Y cuál te gustaría obtener si estuvieras del lado del cliente?

Laiv
fuente
1

Si no quieres nada más, puedes usar:

{
    "Utility": {
        "8": "Water",
        "9": "Electricity"
     },
     "Lease Terms": {
        "5": "Minimum 12 month lease",
        "17": "lease negotiable/flexible"
     }
}

Desafortunadamente aquí, JSON solo permite cadenas como claves.

gnasher729
fuente
O potencialmente, "Utility": ["Water","Electricity"]etc.
Caleth
Pero entonces no puedes hacer referencia a ellos. Esperaría que todo esto sea seguido por una matriz que describe miles de casas, y cada una de ellas contiene, por ejemplo, "8", "9", "5".
gnasher729