web-dev-qa-db-ja.com

階層データ用のフラットまたはネストされたJSON?

私は前後に5回切り替えました。これはRESTエンドポイント/api/tags/は内部使用(サードパーティのクライアントなし)のため、私がそれを使用するのは私だけです。

私はこれらの2つの表現の間で決定しています:

フラット

{  
   "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
      },
   ]
}
  • それはややモジュール式です。互換性を損なうことなく、「country」などの別の最上位レイヤーを追加できます。

入れ子

{  
   "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を実行した後でも、これは少し小さくなります。

どちらを使用する必要がありますか。その理由は何ですか。これが個人的な好みの問題である場合、経験豊富な開発者はどの表現を好みますか、そしてその理由は何ですか?

12
dvtan

ユースケースによって異なります。

Statica型付き言語でJSONを使用する場合、構造が型にマップされると大きなメリットがあります。つまり、すべてのキーの名前を事前に知っておく必要があります。

したがって、Javaを使用してサービスを利用することを計画している場合、またはJSONスキーマを使用してそれを文書化することを計画している場合は、1番目がはるかに明確になります(もちろん両方とも動作します)。

8
fdreger

より多くの文脈なしでは言うのは難しい。私は両方で仕事をしてきましたが、徐々に#1に傾くようになりました。一般に、私は洗練よりも単純の方が重要だと思っています。

#1ではエンティティと関係が明確で明白ですが、#2では別の考え方が必要です。一部の人々にとって、(データ構造としての)木はそれほど自明ではありません。 Person> Addressよりも深い構成|集約をほとんど見たことがないジュニア開発者を考えてみてください。

私は#1を次のように読むことができます:

  • 型付きタグのコレクションがあります

しかし、どうすれば7語だけで#2を説明できますか?ツリー構造に慣れていない場合は、#2を次のように読むことができます

  • タグには2つの属性5と17がありますが、タイプはわかりません。タイプが何であれ、1つの属性textがあります

誤解しないでください。#2はスマートなソリューションである可能性がありますが、読みやすさを不必要に巧妙(または効率)に犠牲にすることはしません。

この回答の執筆時に、私はサードパーティのサービスと統合する必要のあるプロジェクトに取り組んでいます。このサービスは、#2と非常によく似ています。サービスはカレンダーを提供しています:年、月、日、時間

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

Java開発者の私としては、ゲッター|セッター|コンストラクターを介したクラスへの直接マッピングがないため、サービス応答のデシリアライズは最終的にはコードの読み取りが困難になります。代わりに、ドキュメントを走査(getNode、getSiblings、getNodeName、getChildAsText、isNodeObject、isText、etc)し、クラスの階層を手動で入力します。最後に、数値のツリーをタイムスタンプのコレクションにマップすることに成功しました!どの読みやすく、逆シリアル化する方が簡単だと思いますか?クライアント側にいる場合、どの構造を取得しますか?

4
Laiv

他に何もしたくない場合は、次のように使用できます。

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

残念なことに、JSONはキーとして文字列のみを許可します。

1
gnasher729