Serializing your records

Please be sure of your agent type and version and pick the right documentation accordingly.

This is the documentation of the forest-express-sequelize and forest-express-mongoose Node.js agents that will soon reach end-of-support.

forest-express-sequelize v9 and forest-express-mongoose v9 are replaced by @forestadmin/agent v1.

Please check your agent type and version and read on or switch to the right documentation.

Serializing your records

To be interpreted correctly by the ForestAdmin UI, the data must be sent from your admin backend using a particular structure. This structure needs to comply to the JSON API standard. The JSON API standard is used to ensure a standardized way to format JSON responses returned to clients. You can find some more information directly from their website. Most of the time, your admin backend will handle this for you, and you will not have to play with serialization. However you might encounter specific use cases that will require you to serialize data yourself, such as smart collections for example.‌

In order to help you do so, the helper RecordSerializer is made available through the packages built-in your admin panel.‌

Initializing the record serializer

const { RecordSerializer } = require('forest-express-sequelize');​

const recordSerializer = new RecordSerializer({ name: 'customer_stats' });

To make use of the serializer, simply get it from your agent package, and initialize it with a collection of yours. The serializer will retrieve the structure of the collection, and thus, will know which attributes it needs to take in to perform the serialization.1‌

Example 1 - Smart collection with simple fields

Let's take a look at the collection defined in the documentation's smart collection example:

/forest/customer_stats.js
const { collection } = require('forest-express-sequelize');

collection('customer_stats', {
  isSearchable: true,
  fields: [
    {
      field: 'email',
      type: 'String',
    },
    {
      field: 'orders_count',
      type: 'Number',
    },
    {
      field: 'total_amount',
      type: 'Number',
    },
  ],
});

The serializer exposes a .serialize() method that takes as an argument an array of objects (or a single object). In the smart collection example, this array would be as such:

const records = [
  {
    id: 67427,
    email: 'janessa_langosh@example.net',
    orders_count: '4',
    total_amount: 93800,
    created_at: 2018-03-19T14:59:59.440Z,
    updated_at: 2018-03-19T15:00:00.443Z
  },
  {
    id: 67429,
    email: 'dortha90@example.net',
    orders_count: '3',
    total_amount: 106700,
    created_at: 2018-03-19T15:00:08.430Z,
    updated_at: 2018-03-19T15:00:09.134Z
  },
  ...
]

To perform the serialization just use the .serialize() method like this:

const serializedRecords = recordSerializer.serialize(records);

The serialized records are formatted as follows:

{
  data: [
    {
      type: 'customer_stats',
      id: '67427',
      attributes: {
        email: 'janessa_langosh@example.net',
        orders_count: '4',
        total_amount: 93800
      }
    },
    {
      type: 'customer_stats',
      id: '67429',
      attributes: {
        email: 'dortha90@example.net',
        orders_count: '3',
        total_amount: 106700
      },
    },
    ...
  ]
}

This is the proper format expected by the UI to correctly display the records.‌

Example 2 - Smart collection example with an added belongsTo relationship

Now let's say we want to reference the customer related to a stat instead of just displaying its email. We would then adapt the smart collection definition to include a field customer referencing the customers collection:

/forest/customer_stats.js
const { collection } = require('forest-express-sequelize');

collection('customer_stats', {
  isSearchable: true,
  fields: [
    {
      field: 'orders_count',
      type: 'Number',
    },
    {
      field: 'total_amount',
      type: 'Number',
    },
    {
      field: 'customer',
      type: 'String',
      reference: 'customers.id',
    },
  ],
});

For the belongsTo relationship to be properly serialized, the records passed on to the serializer should include the related object (here customer), following this structure:

const records = [
  {
    id: 67427,
    customer: {
      id: 27048
    },
    orders_count: '4',
    total_amount: 93800,
    created_at: 2018-03-19T14:59:59.440Z,
    updated_at: 2018-03-19T15:00:00.443Z
  },
  {
    id: 67429,
    customer: {
      id: 27049
    },
    orders_count: '3',
    total_amount: 106700,
    created_at: 2018-03-19T15:00:08.430Z,
    updated_at: 2018-03-19T15:00:09.134Z
  },
  ...
]

Now if we try to serialize this data, the serializer will automatically detect that the records to be serialized include another record (customer in this case), based on the collection definition.‌

The included records will then be picked up and wrapped to comply to the JSON API relationships format.

const serializedRecords = recordsSerializer.serialize(records);

The serialized records are formatted as follows:

{
  data: [
    {
      type: 'customer_stats',
      id: '67427',
      attributes: {
        orders_count: '4',
        total_amount: 93800
      },
      relationships: {
        customer: {
          data: {type: "customers", id: "27048"}
          links: {related: {href: "/forest/customer_stats/67427/relationships/customer"}}
        }
      }
    },
    ...
  ],
  included: [
    {
      type: "customers"
      id: "27048"
      attributes: {
        id: 27048
      }
    },
    ...
  ]
}

Note that the customer relationship is clearly indicated under the relationships attribute. Also note that the customer is automatically wrapped in the included section, with its attributes if you specified some (only id in this case).

Last updated