Building an object from a heterogeneous collection


#1

So “data” can be a heterogeneous collection. Our clientside guys ask us for an ability to map that collection to definite fields by type.

Example

{
  "data": [
    {
      "id": 1,
      "type": "a",
      "attributes": {"k":10}
    },
    {
      "id": 2,
      "type": "a",
      "attributes": {"k":42}
    },
    {
      "id": 1,
      "type": "b",
      "attributes": {"m":"n", "s":100}
    },
  ]
}

We need to convert it to

{
  "field_a": [
    {
      "id": 1,
      "type": "a",
      "attributes": {"k":10}
    },
    {
      "id": 2,
      "type": "a",
      "attributes": {"k":42}
    },
  ],
  "field_b": [
    {
      "id": 1,
      "type": "b",
      "attributes": {"m":"n", "s":100}
    },
  ]
}

and later to

{
  "field_a": [
    {
      "k":10
    },
    {
      "k":42
    },
  ],
  "field_b": [
    {
      "m":"n", 
      "s":100
    },
  ]
}

It’s needed in order to use straight mapping to templates: we have to know how to address to a collection of “a” type and of “b” type.

So we decided to use “meta”

{
  "meta": {
    "schema": [
      {"name":"field_a", "type":"a"},
      {"name":"field_b", "type":"b"},
    ]
  }
}

Are we doing something wrong? Are there any best practices for handling heterogeneous collections in “data”? Any advice is appreciated.


#2

Moving @tkellen’s comment from https://github.com/json-api/json-api/issues/806

Could you do something along these lines before sending it to the template?

const data = [
  { id: "1", type: "a", attributes: { field: "1a" } },
  { id: "1", type: "b", attributes: { field: "1b" } }
];
const namespacedData = data.reduce(function (result, item) {
  const type = item.type;
  if (!result[type]) {
    result[type] = [];
  }
  result[type].push(item);
  return result;
}, {});

We thought about grouping by type, but it looks dirty: we have carefully chosen attributes and relationships names, and here that weird type-based names come. We want meaningful names for all the fields.


#3

The JSON-API format is not architected for ease of use with templating, I think your approach with meta is totally sound!