13

I've switched back and forth ~5 times already. This REST endpoint at /api/tags/ will be for internal use (no 3rd party clients), I'm the only one working with it.

I'm deciding between these two representations:

Flat

{ 
 "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
 },
 ]
}
  • It's somewhat modular. Can add another top layer such as "country" without breaking compatibility.

Nested

{ 
 "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"
 },
 }
 },
}
  • It's already in a usable format. Don't need to loop through data before using it.
  • Saves some bandwidth. Even after gzip, this is slightly smaller.

Which one should be used, and why? If this is a matter of personal preference, which representation would experienced developers prefer and why?

asked Jun 10, 2017 at 20:59
9
  • Is this a matter of personal preference?. I think so. Requirements > needs > preferences Commented Jun 10, 2017 at 21:19
  • 3
    @Laiv In that case, my question should be rephrased "Which representation do experienced developers prefer and why?" Commented Jun 10, 2017 at 21:34
  • Are these id's stable over time and ok for the client to remember and use later, or, are they just message local? Commented Jun 10, 2017 at 23:35
  • @ErikEidt They're permanent, database primary keys. Commented Jun 11, 2017 at 0:34
  • Do you consider Water more as a subclass of Utility or more as an instance of Utility? Commented Jun 11, 2017 at 0:43

3 Answers 3

10

Depends on your use case.

When using JSON with statica typed languages, there is a huge bonus if your structure maps to your types. This means that all the names of the keys should be known in advance.

So, if you plan to use Java to consume the service, or if you plan to document it with JSON Schema, number one will be much cleaner (of course both will work).

Laiv
15k2 gold badges34 silver badges71 bronze badges
answered Jun 11, 2017 at 8:31
5

Hard to say without more context. I have worked with both but progressively I started to lean to #1. In general, I have found simplicity more relevant than sophistication.

In #1, entities and relationships are clear and obvious, whereas #2 requires a different way of thinking. For some people, trees (as data structures) are not that self-descriptives. Think in junior developers who barely have seen a composition|aggregation deeper than Person> Address.

I could read #1 as:

  • there's a collection of typed tags.

But, how could we describe #2 only in 7 words? If I were unfamiliar with tree structures I could read #2 as

  • tags have two attributes 5 and 17, but I don't know their types. Whatever the type is, has one attribute, text.

Don't get me wrong, #2 could be a smart solution, but I would not sacrifice readability for cleverness (or efficiency) unnecessarily.

At the writing of this answer, I'm working on a project which needs to be integrated with a 3rd party service which responses are very similar to #2. The service is providing us with a calendar: year, months, days and hours of the day

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

As Java developer I am, the deserialization of the service response ended up in code that is anything but readable because there's no direct mapping to classes through getters|setters|constructors. Instead, I have had to traverse the document (getNode, getSiblings, getNodeName, getChildAsText, isNodeObject, isText, etc) and populate my hierarchy of classes manually. Finally, I managed to map the tree of numbers into a collection of timestamps! Which structure would you say is easier to read and deserialise? And which one would you like to get if you were on the client-side?

answered Jun 11, 2017 at 13:35
2

If you didn't want anything else, you could just use:

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

Unfortunate here that JSON only allows strings as keys.

answered Jun 11, 2017 at 15:54
2
  • Or potentially "Utility": ["Water","Electricity"] etc Commented Jun 18, 2019 at 9:49
  • But then you can’t reference them. I’d expect all this to be followed by an array describing thousand houses, and each containing for example "8", "9", "5". Commented Feb 2, 2020 at 9:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.