0

Is there any reason not to build JSON data that can be indexed by some key? For example in the WhenIWork API below, using the user's id to quickly access the data? The reason I'm asking is because it seems that for a lot of uses on the client side you could easily index into the array then and grab the data you need vs. looping through the JSON array looking for a specific id. But a lot of APIs do not do this (2 of those examples below).

WhenIWork API -- Users

{
  "users": [
    {
      "id": 4364,
      "login_id": 2112,

      "first_name": "Goldie",
      "last_name": "Wilson",

    },
    {
      "id": 27384,
      "login_id": 2112,

      "email": "jen.parker@example.com",
      "first_name": "Jennifer",
      "last_name": "Parker",

    }
  ]
}

GitHub API -- Events

[
  {
    "type": "Event",
    "public": true,
    "payload": {
    },
    "repo": {
      "id": 3,
      "name": "octocat/Hello-World",
      "url": "https://api.github.com/repos/octocat/Hello-World"
    },
    "actor": {
      "id": 1,
      "login": "octocat",
      "gravatar_id": "",
      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
      "url": "https://api.github.com/users/octocat"
    },
    "org": {
      "id": 1,
      "login": "github",
      "gravatar_id": "",
      "url": "https://api.github.com/orgs/github",
      "avatar_url": "https://github.com/images/error/octocat_happy.gif"
    },
    "created_at": "2011-09-06T17:26:27Z",
    "id": "12345"
  }
]

In my specific case I have a users portion of the API which gives me data similar to the code above. Then by going to users/availability I can get all the availability for users. But right now I have to loop through all the data looking for specific IDs.

{
  [
    {
      "user_id":"41",
      "date":"2017-07-01",
      "status":"Unavailable"
    },
    {
      "user_id":"41",
      "date":"2017-07-02",
      "status":"Available"},,
  [
    {
      "user_id":"47",
      "date":"2017-07-01",
      "status":"Available"
    },
    {
      "user_id":"47",
      "date":"2017-07-02",
      "status":"Leave\/TDY"
    }
  ]
}
1

I think the reason most API's represent those data structures with arrays instead of objects is because arrays inherently support iteration, but objects don't. For example, to iterate over the keys in an JSON object in JavaScript, you must inspect the object's properties (but avoid certain properties) using Object.keys or something similar. Iteration is more natural if arrays are used, and an "index" can be built very simply by iterating over the array once.

arr.reduce((index, item) => Object.extend({}, index, {[item.id]: item}), {})

Another reason an API might use an array over an object is that it reflects the format that data is fetched from persistance. In every database I've used results are always represented collection (e.g. SQL query rows), not a map, so it's natural to carry that structure to the interface layer without changing it. Further collections work regardless of whether there is a unique key or not, but maps work best with a unique key.

Finally--arrays are an ordered type. If the order of results has meaning (like events in a timeline), then returning a map wouldn't be very useful because the order of properties in JSON is not intended to be maintained.

  • Couldn't the API do something like: $results = array(); while($row = mysqli_fetch_assoc($result)) { $results[$row['id']][] = $row; } Before returning the JSON response to add some type of key? – keelerjr12 Jul 13 '17 at 0:01
  • Futhermore, how do clients of these APIs handle accessing data quickly? O(1) time-complexity vs O(n)? – keelerjr12 Jul 13 '17 at 0:04
  • 2
    @keelerjr12 They preprocess the data into more suitable structures client-side. This is akin to (manually) building an index. Often when you access an end-point that returns bulk results, you want to do something with all of the results, so a linear pass over the data isn't a problem. This kind of manual restructuring of the data is one of the things Relay/GraphQL was designed to resolve. – Derek Elkins Jul 13 '17 at 0:35
  • Counterpoint. Iterating with Object.keys() is simple. Most database rows have a unique ID so returning them as a Map "works". Most languages have ordered versions of Maps. I think it's mainly "habit" and "tradition" that programs return arrays instead of Maps. – user949300 Jul 13 '17 at 1:35
  • On 2nd thought, you probably don't want to expose a DB row's ID, so ignore that part of my comment. – user949300 Jul 13 '17 at 5:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.