JSON plat ou imbriqué pour les données hiérarchiques?

12

J'ai déjà fait des allers-retours ~ 5 fois. Ce point de terminaison REST /api/tags/sera à usage interne (pas de clients tiers), je suis le seul à travailler avec.

Je décide entre ces deux représentations:

Plat

{  
   "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
      },
   ]
}
  • C'est un peu modulaire. Peut ajouter une autre couche supérieure telle que "pays" sans casser la compatibilité.

Imbriqué

{  
   "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"
         },
      }
   },
}
  • C'est déjà dans un format utilisable. Pas besoin de parcourir les données avant de les utiliser.
  • Économise de la bande passante. Même après gzip, c'est légèrement plus petit.

Lequel devrait être utilisé et pourquoi? S'il s'agit d'une préférence personnelle, quelle représentation les développeurs expérimentés préféreraient-ils et pourquoi?

dvtan
la source
Is this a matter of personal preference?. Je le pense. Exigences> besoins> préférences
Laiv
1
@Laiv Dans ce cas, ma question devrait être reformulée "Quelle représentation préfèrent les développeurs expérimentés et pourquoi?"
dvtan
Ces identifiants sont-ils stables dans le temps et peuvent-ils être mémorisés et utilisés ultérieurement par le client, ou s'agit-il simplement d'un message local?
Erik Eidt
@ErikEidt Ce sont des clés primaires de base de données permanentes.
dvtan
Considérez-vous l'eau plus comme une sous-classe d'utilité ou plus comme une instance d'utilité?
Erik Eidt

Réponses:

8

Cela dépend de votre cas d'utilisation.

Lorsque vous utilisez JSON avec des langages typés statica, il y a un énorme bonus si votre structure correspond à vos types. Cela signifie que tous les noms des clés doivent être connus à l'avance.

Donc, si vous prévoyez d'utiliser Java pour consommer le service, ou si vous prévoyez de le documenter avec le schéma JSON, le numéro un sera beaucoup plus propre (bien sûr, les deux fonctionneront).

fdreger
la source
4

Difficile à dire sans plus de contexte. J'ai travaillé avec les deux mais progressivement j'ai commencé à m'appuyer sur le n ° 1. En général, j'ai trouvé la simplicité plus pertinente que la sophistication.

Dans # 1, les entités et les relations sont claires et évidentes, tandis que # 2 nécessite une manière différente de penser. Pour certaines personnes, les arbres (en tant que structures de données) ne sont pas auto-descriptifs. Pensez aux développeurs juniors qui ont à peine vu une composition | agrégation plus profonde que Personne> Adresse .

Je pourrais lire # 1 comme:

  • il y a une collection de balises typées .

Mais, comment pourrions-nous décrire # 2 seulement en 7 mots? Si je ne connaissais pas les structures arborescentes, je pourrais lire # 2 comme

  • les balises ont deux attributs 5 et 17, mais je ne connais pas leurs types. Quel que soit le type, a un attribut, le texte .

Ne vous méprenez pas, # 2 pourrait être une solution intelligente, mais je ne sacrifierais pas inutilement la lisibilité pour l'intelligence (ou l'efficacité).

Au moment de la rédaction de cette réponse, je travaille sur un projet qui doit être intégré à un service tiers dont les réponses sont très similaires à # 2. Le service nous fournit un calendrier: année, mois, jours et heures de la journée

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

En tant que développeur Java, je suis, la désérialisation de la réponse du service a abouti à un code qui est tout sauf lisible car il n'y a pas de mappage direct vers les classes via les constructeurs getters | setters |. Au lieu de cela, j'ai dû parcourir le document ( getNode, getSiblings, getNodeName, getChildAsText, isNodeObject, isText, etc.) et remplir ma hiérarchie de classes manuellement. Enfin, j'ai réussi à mapper l'arbre des nombres dans une collection d'horodatages! Selon vous, quelle structure est plus facile à lire et à désérialiser? Et lequel aimeriez-vous obtenir si vous étiez du côté client?

Laiv
la source
1

Si vous ne vouliez rien d'autre, vous pouvez simplement utiliser:

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

Malheureusement, JSON n'autorise que les chaînes comme clés.

gnasher729
la source
Ou potentiellement "Utility": ["Water","Electricity"]etc
Caleth
Mais alors vous ne pouvez pas les référencer. Je m'attendrais à ce que tout cela soit suivi d'un tableau décrivant des milliers de maisons, chacune contenant par exemple «8», «9», «5».
gnasher729