Плоский или вложенный JSON для иерархических данных?

12

Я переключался туда и обратно ~ 5 раз уже. Эта конечная точка REST по /api/tags/желанию предназначена для внутреннего использования (без сторонних клиентов), я единственный, кто работает с ней.

Я выбираю между этими двумя представлениями:

Плоский

{  
   "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
      },
   ]
}
  • Это несколько модульно. Можно добавить еще один верхний слой, например «страна», не нарушая совместимость.

Уплотненный

{  
   "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"
         },
      }
   },
}
  • Это уже в удобном для использования формате. Не нужно перебирать данные перед использованием.
  • Сохраняет некоторую пропускную способность. Даже после gzip это немного меньше.

Какой из них следует использовать и почему? Если это вопрос личных предпочтений, какое представление предпочитают опытные разработчики и почему?

dvtan
источник
Is this a matter of personal preference?, Я думаю так. Требования> потребности> предпочтения
Laiv
1
@Laiv В таком случае мой вопрос должен быть перефразирован: «Какое представление предпочитают опытные разработчики и почему?»
Двтан
Являются ли эти идентификаторы стабильными с течением времени и могут ли клиенты их запомнить и использовать позже, или они просто являются локальными сообщениями?
Эрик Эйдт
@ErikEidt Это постоянные первичные ключи базы данных.
Двтан
Считаете ли вы воду больше подклассом полезности или больше как пример полезности?
Эрик Эйдт

Ответы:

8

Зависит от вашего варианта использования.

При использовании JSON со статическими типизированными языками есть огромный бонус, если ваша структура соответствует вашим типам. Это означает, что все названия ключей должны быть известны заранее.

Итак, если вы планируете использовать Java для использования сервиса или планируете документировать его с помощью JSON Schema, номер один будет намного чище (конечно, оба будут работать).

fdreger
источник
4

Трудно сказать без контекста. Я работал с обоими, но постепенно я начал склоняться к # 1. В общем, я нашел простоту более актуальной, чем изощренность.

В # 1 сущности и отношения ясны и очевидны, тогда как # 2 требует другого мышления. Для некоторых людей деревья (как структуры данных) не настолько информативны. Подумайте о младших разработчиках, которые едва видели композицию | агрегацию глубже, чем Person> Address .

Я мог прочитать # 1 как:

  • есть коллекция напечатанных тегов .

Но как мы могли бы описать № 2 только в 7 словах? Если бы я не был знаком с древовидными структурами, я мог бы прочитать № 2 как

  • у тегов есть два атрибута 5 и 17, но я не знаю их типы. Независимо от типа, имеет один атрибут, текст .

Не поймите меня неправильно, # 2 может быть разумным решением, но я бы не стал жертвовать читабельностью ради хитрости (или эффективности) без необходимости.

При написании этого ответа я работаю над проектом, который необходимо интегрировать со сторонним сервисом, ответы которого очень похожи на # 2. Сервис предоставляет нам календарь: год, месяцы, дни и часы дня

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

Как разработчик Java, десериализация ответа службы закончилась в коде, который совсем не читается, потому что нет прямого сопоставления с классами через getters | setters | constructors. Вместо этого мне пришлось пройти по документу ( getNode, getSiblings, getNodeName, getChildAsText, isNodeObject, isText и т. Д.) И заполнить иерархию классов вручную. Наконец, мне удалось отобразить дерево чисел в коллекцию временных меток! Какую структуру, по-вашему, легче читать и десериализовать? А какую бы вы хотели получить, если бы были на стороне клиента?

LAIV
источник
1

Если вы не хотите ничего другого, вы можете просто использовать:

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

К сожалению, здесь JSON допускает только строки в качестве ключей.

gnasher729
источник
Или потенциально и "Utility": ["Water","Electricity"]т. Д.
Caleth
Но тогда вы не можете ссылаться на них. Я ожидаю, что за всем этим последует массив, описывающий тысячи домов, каждый из которых содержит, например, «8», «9», «5».
gnasher729