Плоский або вкладений 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 це трохи менше.

Який слід використовувати і чому? Якщо це питання особистого уподобання, яке представництво воліють розробники та чому?


Is this a matter of personal preference?. Я думаю так. Вимоги> потреби> уподобання
Laiv

1
@Laiv У цьому випадку моє запитання слід перефразувати "Якому представництву надають перевагу досвідчені розробники і чому?"
dvtan

Чи стабільні ці ідентифікатори з часом і нормально, щоб клієнт запам'ятав і використовував їх пізніше, чи вони просто місцеві?
Ерік Ейдт

@ErikEidt Вони є постійними первинними ключами бази даних.
dvtan

Ви розглядаєте Воду більше як підклас Utility або більше як примірник Utility?
Ерік Ейдт

Відповіді:


8

Залежить від вашого випадку використання.

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

Отже, якщо ви плануєте використовувати Java для споживання послуги, або якщо ви плануєте документувати її за допомогою схеми JSON, номер один буде набагато чистішим (звичайно, обидва будуть працювати).


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 | конструкторів. Натомість мені довелося перемістити документ ( getNode, getSiblings, getNodeName, getChildAsText, isNodeObject, isText тощо) та заповнити свою ієрархію класів вручну. Нарешті мені вдалося скласти дерево чисел у колекцію часових позначок! Яку структуру, на вашу думку, простіше читати та десеріалізувати? І який би ви хотіли отримати, якби були на стороні клієнта?


1

Якщо ви нічого не хотіли, ви можете просто скористатися:

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

Тут невдало, що JSON допускає лише рядки як клавіші.


Або потенційно "Utility": ["Water","Electricity"]тощо
Caleth

Але тоді ви не можете посилатися на них. Я б очікував, що за всім цим буде дотримуватися масив, що описує тисячі будинків, і кожен з них містить, наприклад, "8", "9", "5".
gnasher729
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.