jsonapi-serializer icon indicating copy to clipboard operation
jsonapi-serializer copied to clipboard

meta data for Resource Identifier Objects

Open sl-ffx opened this issue 3 years ago • 0 comments

I want to serialize a set of entities with relationships and their pivot values. I think the pivot values has to be a part of the Resource Identifier Object. The json:api specification allows the Resource Identifier Object to have a meta field. (see paragraph here) My suggestion is to add a meta field to the Resource Identifier Object here

Here is a small example: We have 2 users and 2 Websites. Every user belongs to multiple websites with different roles. In the database we would have tables for "users", "websites" and a joining table "users_websites" which contains the id of the user, the id of the website and a pivot field "role". The data to serialize could look like this

var data = [
  {
    id: 1,
    name: 'Sandro Labana',
    websites: [
      {
        id: 1,
        url: 'test.foo',
        meta: {
          pivot: {
            role: 'admin'
          }
        }
      },
      {
        id: 2,
        url: 'test.bar',
        meta: {
          pivot: {
            role: 'dev'
          }
        }
      }
    ]
  },
  {
    id: 1,
    name: 'Julian Balardo',
    websites: [
      {
        id: 1,
        url: 'test.foo',
        meta: {
          pivot: {
            role: 'dev'
          }
        }
      },
      {
        id: 2,
        url: 'test.bar',
        meta: {
          pivot: {
            role: 'user'
          }
        }
      }
    ]
  }
];
var JSONAPISerializer = require('jsonapi-serializer').Serializer;
 
var UserSerializer = new JSONAPISerializer('users', {
  attributes: ['name', 'websites'],
  websites: {
    attributes: ['url'],
    ref: 'id'
  }
});
 
JSON.stringify(UserSerializer.serialize(data), null, 2)

And here is how the result of my suggestions would look like

{
  "data": [
    {
      "type": "users",
      "id": "1",
      "attributes": {
        "name": "Sandro Labana"
      },
      "relationships": {
        "websites": {
          "data": [
            {
              "type": "websites",
              "id": "1",
              "meta": {
                "pivot": {
                  "role": "admin"
                }
              }
            },
            {
              "type": "websites",
              "id": "2",
              "meta": {
                "pivot": {
                  "role": "dev"
                }
              }
            }
          ]
        }
      }
    },
    {
      "type": "users",
      "id": "1",
      "attributes": {
        "name": "Julian Balardo"
      },
      "relationships": {
        "websites": {
          "data": [
            {
              "type": "websites",
              "id": "1",
              "meta": {
                "pivot": {
                  "role": "dev"
                }
              }
            },
            {
              "type": "websites",
              "id": "2",
              "meta": {
                "pivot": {
                  "role": "user"
                }
              }
            }
          ]
        }
      }
    }
  ],
  "included": [
    {
      "type": "websites",
      "id": "1",
      "attributes": {
        "url": "test.foo"
      },
      "relationships": {}
    },
    {
      "type": "websites",
      "id": "2",
      "attributes": {
        "url": "test.bar"
      },
      "relationships": {}
    }
  ]
}

What do you say? Is there a possibility to implement something like this?

Thanks a lot and sorry for the long post.

sl-ffx avatar Apr 14 '22 13:04 sl-ffx