JSON simples ou aninhado para dados hierárquicos?

12

Já mudei de um lado para o outro ~ 5 vezes. Esse ponto de extremidade REST /api/tags/será para uso interno (sem clientes de terceiros), eu sou o único que trabalha com ele.

Estou decidindo entre essas duas representações:

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
      },
   ]
}
  • É um pouco modular. Pode adicionar outra camada superior, como "país", sem quebrar a compatibilidade.

Aninhado

{  
   "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"
         },
      }
   },
}
  • Já está em um formato utilizável. Não precisa percorrer os dados antes de usá-los.
  • Economiza largura de banda. Mesmo após o gzip, isso é um pouco menor.

Qual deles deve ser usado e por quê? Se isso é uma questão de preferência pessoal, qual representação os desenvolvedores experientes preferem e por quê?

dvtan
fonte
Is this a matter of personal preference?. Acho que sim. Requisitos> necessidades> preferências
Laiv
1
@ Laiv Nesse caso, minha pergunta deve ser reformulada "Qual representação os desenvolvedores experientes preferem e por quê?"
dvtan
Esses IDs são estáveis ​​ao longo do tempo e ok para o cliente lembrar e usar mais tarde ou são apenas mensagens locais?
precisa
@ErikEidt São chaves primárias permanentes de banco de dados.
dvtan
Você considera Água mais como uma subclasse de Utilitário ou mais como uma instância de Utilitário?
precisa

Respostas:

8

Depende do seu caso de uso.

Ao usar JSON com linguagens de tipo estático, há um grande bônus se sua estrutura é mapeada para seus tipos. Isso significa que todos os nomes das chaves devem ser conhecidos antecipadamente.

Portanto, se você planeja usar Java para consumir o serviço, ou se planeja documentá-lo com o JSON Schema, o número um será muito mais limpo (é claro que ambos funcionarão).

fdreger
fonte
4

Difícil dizer sem mais contexto. Eu trabalhei com ambos, mas progressivamente comecei a me inclinar para o número 1. Em geral, achei a simplicidade mais relevante que a sofisticação.

No primeiro, as entidades e os relacionamentos são claros e óbvios, enquanto o segundo exige uma maneira diferente de pensar. Para algumas pessoas, as árvores (como estruturas de dados) não são auto-descritivas. Pense em desenvolvedores juniores que mal viram uma agregação de composição mais profunda do que Pessoa> Endereço .

Eu poderia ler # 1 como:

  • há uma coleção de tags digitadas .

Mas, como poderíamos descrever o número 2 apenas em 7 palavras? Se eu não estivesse familiarizado com as estruturas das árvores, poderia ler # 2 como

  • as tags têm dois atributos 5 e 17, mas não conheço seus tipos. Qualquer que seja o tipo, tem um atributo, texto .

Não me entenda mal, o número 2 poderia ser uma solução inteligente, mas eu não sacrificaria a legibilidade por esperteza (ou eficiência) desnecessariamente.

Ao escrever esta resposta, estou trabalhando em um projeto que precisa ser integrado a um serviço de terceiros cujas respostas sejam muito semelhantes ao nº 2. O serviço está nos fornecendo um calendário: ano, meses, dias e horas do dia

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

Como desenvolvedor de Java, eu sou, a desserialização da resposta do serviço acabou em código que é tudo menos legível, porque não há mapeamento direto para as classes através de construtores getters | setters |. Em vez disso, tive que percorrer o documento ( getNode, getSiblings, getNodeName, getChildAsText, isNodeObject, isText etc.) e preencher minha hierarquia de classes manualmente. Finalmente, consegui mapear a árvore de números em uma coleção de carimbos de data e hora! Qual estrutura você diria que é mais fácil de ler e desserializar? E qual você gostaria de obter se estivesse do lado do cliente?

Laiv
fonte
1

Se você não quisesse mais nada, poderia usar:

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

Infelizmente aqui o JSON permite apenas cadeias de caracteres como chaves.

gnasher729
fonte
Ou potencialmente "Utility": ["Water","Electricity"]etc
Caleth
Mas então você não pode fazer referência a eles. Eu esperaria que tudo isso fosse seguido por uma matriz descrevendo milhares de casas, e cada uma contendo, por exemplo, "8", "9", "5".
gnasher729