JSON piatto o nidificato per dati gerarchici?


12

Sono passato avanti e indietro ~ 5 volte già. Questo endpoint REST presso /api/tags/sarà per uso interno (nessun client di terze parti), sono l'unico che ci lavora.

Sto decidendo tra queste due rappresentazioni:

Piatto

{  
   "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
      },
   ]
}
  • È in qualche modo modulare. È possibile aggiungere un altro livello superiore come "Paese" senza interrompere la compatibilità.

Nidificato

{  
   "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"
         },
      }
   },
}
  • È già in un formato utilizzabile. Non è necessario eseguire il ciclo dei dati prima di utilizzarli.
  • Salva un po 'di larghezza di banda. Anche dopo gzip, questo è leggermente più piccolo.

Quale dovrebbe essere usato e perché? Se si tratta di una preferenza personale, quale rappresentazione preferirebbero gli sviluppatori esperti e perché?


Is this a matter of personal preference?. Credo di si. Requisiti> bisogni> preferenze
Laiv

1
@Laiv In tal caso, la mia domanda dovrebbe essere riformulata "Quale rappresentazione preferiscono gli sviluppatori esperti e perché?"
dvtan,

Questi ID sono stabili nel tempo e ok per il client da ricordare e utilizzare in seguito, oppure sono solo messaggi locali?
Erik Eidt,

@ErikEidt Sono chiavi primarie permanenti del database.
dvtan,

Consideri Water più come una sottoclasse di Utility o più come istanza di Utility?
Erik Eidt,

Risposte:


8

Dipende dal tuo caso d'uso.

Quando usi JSON con linguaggi tipizzati statica, c'è un enorme bonus se la tua struttura si adatta ai tuoi tipi. Ciò significa che tutti i nomi delle chiavi dovrebbero essere conosciuti in anticipo.

Quindi, se prevedi di utilizzare Java per utilizzare il servizio o se prevedi di documentarlo con JSON Schema, il numero uno sarà molto più pulito (ovviamente entrambi funzioneranno).


4

Difficile a dirsi senza più contesto. Ho lavorato con entrambi ma progressivamente ho iniziato ad appoggiarmi al n. 1. In generale, ho trovato la semplicità più pertinente della raffinatezza.

Nel n. 1, entità e relazioni sono chiare ed evidenti, mentre il n. 2 richiede un diverso modo di pensare. Per alcune persone, gli alberi (come strutture di dati) non sono auto-descrittivi. Pensa agli sviluppatori junior che hanno visto a malapena una composizione | aggregazione più profonda di Persona> Indirizzo .

Potrei leggere il n. 1 come:

  • c'è una raccolta di tag digitati .

Ma come possiamo descrivere il n. 2 solo in 7 parole? Se non avessi familiarità con le strutture ad albero potrei leggere il n. 2 come

  • i tag hanno due attributi 5 e 17, ma non conosco i loro tipi. Qualunque sia il tipo, ha un attributo, testo .

Non fraintendetemi, il secondo potrebbe essere una soluzione intelligente, ma non sacrificherei inutilmente la leggibilità per intelligenza (o efficienza).

Al momento della stesura di questa risposta, sto lavorando a un progetto che deve essere integrato con un servizio di terze parti le cui risposte sono molto simili al n. 2. Il servizio ci fornisce un calendario: anno, mesi, giorni e ore del giorno

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

In qualità di sviluppatore Java, la deserializzazione della risposta del servizio è finita in un codice tutt'altro che leggibile perché non esiste un mapping diretto alle classi attraverso i costruttori | setter | costruttori. Invece, ho dovuto attraversare il documento ( getNode, getSiblings, getNodeName, getChildAsText, isNodeObject, isText, ecc.) E popolare manualmente la mia gerarchia di classi. Finalmente sono riuscito a mappare l'albero dei numeri in una raccolta di timestamp! Quale struttura diresti che è più facile da leggere e deserializzare? E quale ti piacerebbe ottenere se fossi sul lato client?


1

Se non volevi nient'altro, potresti semplicemente usare:

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

Purtroppo qui JSON consente solo stringhe come chiavi.


O potenzialmente "Utility": ["Water","Electricity"]ecc.
Caleth,

Ma poi non puoi fare riferimento a loro. Mi aspetterei che tutto ciò sia seguito da una matrice che descriva migliaia di case e ognuna contenente ad esempio "8", "9", "5".
gnasher729,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.