Comparing JSON serializers w/ Rails

Mehdi Noorani
3 min readFeb 17, 2021

Rails as an API

Rails is a great choice as a backend API for your web application as it provides a simple and easy way for rendering JSON data from the backend to the front. Simply, we can make a call in our respective controller:

…. throw in image of the → render :json call

With this call we quickly pass our data from the server to our front end and now it is their problem… right? Wrong. One of the most essential tasks of the backend is to appropriately structure return data so that it can be simply accessed and manipulated on the front end.

What & Why do we serialize?

Serialization is an essential facet to using rails as a backend API and works to solve the very problem presented by the previous section.

Data can be very complex. We want to be able to take our raw data and mend it to better convenience the time of our needy front end developer. Kidding of course.

We could do this manually by:

  1. creating our services folder
  2. creating our 1:1 serializers for corresponding controllers
  3. defining what & how we want our data structured
  4. Make the render :json call

but… we as busy developers don’t have time for that. So, let’s have a gem do the work for us. Additionally, doing so with large structures of data lead to very complex declarations.

Aside — In this post we won’t be fully covering the logistics of serialization, primarily a comparison between the output of 2 like gems. For a resource on that view: https://buttercms.com/blog/json-serialization-in-rails-a-complete-guide

Serializers Gems

Not so fast…you still have to choose which serializer gem you would like to use. Different gems provide slightly different functionality, complexity, and default structure to our return data. However, in essence they all accomplish the same task.

We cover 2 main gems:

  1. Active Model Serializers

This gem is by far the most commonly referenced, is said to be the simplest to work with, and is optimized to work with smaller to medium sets of data.

This gem does have support for simple deep nesting, meaning that we can easily pass data from related models via one JSON render.

Including this gem is as follows:

class OwnerSerializer  attributes :id, :name, :age, :height, :weight
has_many :pets
end

Here, we get a beautiful return structure that includes the specific information for our Owner, as well at the nested information for its respective dog.

{
"id": 1,
"name": "Test",
"age": "test@test.com",
"height": [
{
"id": 1,
"name": "Sparky",
"breed": ["husky", "german Shepard", "golden doodle"]
}
]
}

2. Fast JSON API / Jsonapi-serializer

Previously maintained by Netflix, this gem is said to be better at handling larger sets of data and claims to be 25 times faster than Active Model Serializers.

Does support similar declaration syntax to the previous gem and relationship level calls such as: belongs_to, has_many, has_one. However, I have come to find that this gem make it rather difficult when working with deeply nested data between related models.

Pulling from our last example:

class OwnerSerializer
include FastJsonapi::ObjectSerializer

has_many :pets
attributes :id, :name, :age, :height, :weight
end

We expect when receiving our JSON data that the nested attributes of an owners dogs should also be available. However instead, we get something more along the lines of:

relationships: {
dogs: {
data: [
{
id: "310",
type: "dog"
}
]
}
}

This returns to us essentially a pointer to the data we are looking for but not the data itself. This can be further manipulated to do a search for the respective nested attributes.

Jsonapi-serializer is simply a fork or the original fast JSON API to maintain the project that is longer kept up by Netflix. This fork is relatively young and so far there are not any notable differences between it and its predecessor.

Wouldn’t it be nice if these two just existed in one single gem?

Good News! Certain gems are always being worked on and improved. It may be that in the future Jsonapi-Serializer supports both fast data parsing as well as easy access deeply nested attributes.

Suggestions?

Feel free to leave a comment down below if you enjoyed the port and/or have any suggestions for improving!

--

--