PHP JSON – How to Use Key/Index for Easy Searching

jsonPHP

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"
    }
  ]
}

Best Answer

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.