Mallow's Blog

JSON Serialization in Rails – PART 1

What is JSON?

JSON (JavaScript Object Notation) is a format that can be used to store or exchange data. It is easy to read by humans and easy to parse by machines, which is why a lot of APIs use JSON.

What does the term Serialization refer to?

Serialization in Rails programming is a reference to formatting the JSON output of an API so that each record is unique and carries with it the desired data. There have been a few attempts at standardizing Rails JSON output, with corresponding Ruby gems to do the job. The most common were called “Active Model” serializers.

ActiveModelSerializer:

ActiveModelSerializers brings convention over configuration to your JSON generation. ActiveModelSerializers works through two components: serializers and adapters. Serializers describe which attributes and relationships should be serialized. Adapters describe how attributes and relationships should be serialized.

ActiveModel::Serializer provides a way of creating custom JSON by representing each resource as a class that inherits from ActiveModel::Serializer. With that in mind, it gives us a better way of testing compared to other methods.

Add the following gem to your Gemfile:

gem 'active_model_serializers', '0.9.3'


Then install it using bundle:

bundle install


You can generate a serializer as follows:

rails g serializer post


The above generator will create a serializer in app/serializers/post_serializer.rb with the following content:

# app/serializers/post_serializer.rb
class PostSerializer < ActiveModel::Serializer
end


It is very easy to create complex JSON responses using ActiveModel::Serializer, but it’s strongly discouraged. 

The following examples use basic constraints that you can follow. It should serve the goal of simple and maintainable serializers.

# app/serializers/post_serializer.rb
class PostSerializer < ActiveModel::Serializer
  attributes :title, :description
  has_many :comments
end


It is possible to automatically include all attributes of a model, but it will introduce the risk of accidentally sending sensitive data to the client. It also floods the client with unnecessary data. This is strongly discouraged unless the model has a small attribute set and they rarely change.

In that case, the serializer below serves the purpose of a simple serializer example that includes all attributes automatically

# app/serializers/post_serializer.rb
class PostSerializer < ActiveModel::Serializer
  attributes *Post.column_names
end


Response of the API looked like before the serializer:

{
  "id": 1,
  "title": 'Test 123',
  "description": 'Test',
  "created_at": '2019-08-08 02:36:37.199806',
  "updated_at": '2019-08-08 02:36:37.199806'
},
{
  "id": 2,
  "title": 'Test 124',
  "description": 'Test',
  "created_at": '2019-08-08 02:36:37.199806',
  "updated_at": '2019-08-08 02:36:37.199806'
},
{
  "id": 3,
  "title": 'Test 125',
  "description": 'Test',
  "created_at": '2019-08-08 02:36:37.199806',
  "updated_at": '2019-08-08 02:36:37.199806'
}


After implementing the serializer, the API response looked like this:

{
  "id": 1,
  "title": 'Test 123',
  "description": 'Test',
  "created_at": '2019-08-08 02:36:37.199806',
  "updated_at": '2019-08-08 02:36:37.199806',
  "comments": [
    {
      "id": 6,
      "post_id": 1,
      "content": 'Test comment'
    }
  ]
}


The larger your responses get, you will experience the serialization bottleneck that Rails has long suffered from, partially due to ActiveModel::Serializers. ActiveModelSerializer  is a large library supporting multiple specs, not just JSON API, so it supports many things but not specifically built for high performing API.

Performance is critical to us and to solve this we could use Fast JSON API by Netflix

https://github.com/Netflix/fast_jsonapi

The Netflix JSON serializer is simply called “Fast JSON API.” It presents data in accordance with the new JSON 1.0 standard. But it’s also, well, FAST.

According to its own GitHub post “serialization time is at least 25 times faster than Active Model serializers on up to current benchmarks of 1000 records”.

Using the serializer isn’t hard at all. It really involves just three things: installing/including the gem, creating a serializer, then calling that serializer in the appropriate controller action. You even get access to automatic generation of serializers via “rails generate” commands. It’s all pretty solid, actually! To get going just go to https://github.com/Netflix/fast_jsonapi and follow the very simple instructions.

We will look into Netflix Fast JSON API in next part describing in more detail.

– Logesh M,
ROR Team Lead,
Mallow Technologies.

Leave a Reply

%d bloggers like this: