At Agira, Technology Simplified, Innovation Delivered, and Empowering Business is what we are passionate about. We always strive to build solutions that boost your productivity.

JSON Serialization In Rails: A Complete Guide

  • By Arjunan Subramani
  • September 18, 2018
  • 8198 Views

What Is JSON?

JSON (JavaScript Object Notation) is a lightweight data-interchange format that encodes the object into a string. JSON is completely language independent. It is used in Java, JavaScript, Perl, Python, Ruby, etc. Such data representation can easily be translated between server and client(Browser) but also between server and server. Serialization is a process that transforms an object into that string.

JSON Serialization In Rails

If your rails application is used with popular Javascript frameworks and presents API that utilizes the JSON.
Basically, JSON serialization has two parts,
1) Data preparation
2) Data transformation

Data preparation

Data preparation is converting or transforming Ruby object into a hash. There are various Ruby gems available for you to implement the JSON serialization. In this tutorial, we can use the following gems for preparing JSON data. Now we can create new rails project and models.

rails new json_serialization --database=postgresql
cd json_serialization
rails g model author name:string email:string
rails g model article title:string content:text published:boolean published_at:timestamp author:references
rails g model comment body:text article:references user:string
rake db:create
rake db:migrate

Now we can add association to author model,

class Author < ApplicationRecord
  has_many :articles
end
class Article < ApplicationRecord
  belongs_to :author
  has_many :comments
end

Now run the following command to open rails console,

rails console

Now you can add the required data to the table,

author = Author.create(name: "Anderson", email: "anderson@gmail.com")
article = Article.create(author: author, title: "New Article", content: "Article Content", published_at: Time.now, published:true)
comment = Comment.create(article: article, body: "comment", user: "visitor")

Also Read: Web Automation With Ruby Cucumber And Watir

Active Model Serializers

ActiveModelSerializers used to create custom JSON format by representing serializer as a class which is inherited from ActiveModel::Serializer.
Add the gem into our Gemfile, and run bundle install

gem 'active_model_serializers', '~> 0.10.6'

Now we can generate the serializers for our models

rails g serializer author
rails g serializer article
rails g serializer comment

You could see our generated serializers in the app/serializers directory. Now add the following code into our serializers,

# apps/serializers/author_serializer.rb
class AuthorSerializer < ActiveModel::Serializer
  attributes :id, :name, :email
end
# apps/serializers/article_serializer.rb
class ArticleSerializer < ActiveModel::Serializer
  belongs_to :author
  has_many :comments
  attributes :id, :title, :content, :published_at
end
# apps/serializers/comment_serializer.rb
class CommentSerializer < ActiveModel::Serializer
  attributes :id, :body, :user
end

From Rails console execute the following code to test our serializer,

article = Article.first
ArticleSerializer.new(article).as_json
=> {:id=>1, :title=>"New Article", :content=>"Article Content", :published_at=>Sun, 29 Jul 2018 14:32:20 UTC +00:00, :author=>{:id=>1, :name=>"Anderson", :email=>"anderson@gmail.com"}, :comments=>[{:id=>1, :body=>"comment", :user=>"visitor"}]}

Jbuilder

Jbuilder gem provides a simple DSL for declaring JSON structures. There is no need to add the gem into the gemfile because Jbuilder gem is default available. Now we can create the JSON template in app/view/articles.json.jbuilder and add the following code.

#  app/view/articles.json.jbuilder
json.id article.id
json.title article.title
json.content article.content
json.author do
  json.id article.author.id
  json.user article.author.name
  json.body article.author.email
end
json.comments(article.comments) do |comment|
  json.id comment.id
  json.user comment.user
  json.body comment.body
end

Let’s generate the JSON format from our rails console without using template,

result = Jbuilder.new do |json|
  json.id article.id
  json.title article.title
  json.content article.content
  json.author do
    json.id article.author.id
    json.user article.author.name
    json.email article.author.email
  end
  json.comments(article.comments) do |comment|
    json.id comment.id
    json.user comment.user
    json.body comment.body
  end
end
result.target! => "{\"id\":1,\"title\":\"New Article\",\"content\":\"Article Content\",\"author\":{\"id\":1,\"user\":\"Anderson\",\"email\":\"anderson@gmail.com\"},\"comments\":[{\"id\":1,\"user\":\"visitor\",\"body\":\"comment\"}]}"

# With Template

renderer = ApplicationController.new
renderer.render_to_string('/articles', locals: {article: article})
=> "{\"id\":1,\"title\":\"New Article\",\"content\":\"Article Content\",\"author\":{\"id\":1,\"user\":\"Anderson\",\"email\":\"anderson@gmail.com\"},\"comments\":[{\"id\":1,\"user\":\"visitor\",\"body\":\"comment\"}]}"

JSONAPI-RB

Jsonapi-rb is an intuitive ruby library for producing and consuming JSON API documents. It is comprised of 4 independent micro-libraries: jsonapi-parser, jsonapi-renderer, jsonapi-serializable, jsonapi-deserializable.
Add the gem into our Gemfile, and run bundle install

gem 'jsonapi-rails'

In jaonapi-rb resources are defined by subclass of JSONAPI::Serializable::Resource. Since we have already created serializers so we just need to update our serializers now.

# apps/serializers/article_serializer.rb
class ArticleSerializer < JSONAPI::Serializable::Resource
  type 'articles'
  belongs_to :author
  has_many :comments
  attributes :id, :title, :content
end
# apps/serializers/author_serializer.rb
class AuthorSerializer < JSONAPI::Serializable::Resource
  type 'authors'
  attributes :id, :name, :email
end
# apps/serializers/comment_serializer.rb
class CommentSerializer < JSONAPI::Serializable::Resource
  type 'comments'
  attributes :id, :body, :user, :article_id
end

From Rails console execute the following code to test our serializer

renderer = JSONAPI::Serializable::Renderer.new
article = Article.first
renderer.render(article, class: {Author: AuthorSerializer, Article: ArticleSerializer, Comment: CommentSerializer }, include: [:author, :comments])
=> {:data=>{:id=>"1", :type=>:articles, :attributes=>{:id=>1, :title=>"New Article", :content=>"Article Content"}, :relationships=>{:author=>{:data=>{:type=>:authors, :id=>"1"}}, :comments=>{:data=>[{:type=>:comments, :id=>"1"}]}}}, :included=>[{:id=>"1", :type=>:authors, :attributes=>{:id=>1, :name=>"Anderson", :email=>"anderson@gmail.com"}}, {:id=>"1", :type=>:comments, :attributes=>{:id=>1, :body=>"comment", :user=>"visitor", :article_id=>1}}]}

Also Read: 10 Useful Tips & Tricks for Ruby On Rails Developers

ROAR

Roar (Resource-Oriented Architectures in Ruby) is a framework for parsing and rendering REST documents. Roar gives a DSL and behavior for creating hypermedia APIs.
Add the following gem into our Gemfile and bundle it.

gem "roar"

Now we can create representer for our models under app/representers/ directory,

# app/representers/author_representer.rb
require 'roar/decorator'
require 'roar/json'
class AuthorRepresenter < Roar::Decorator
  include Roar::JSON
  property :id
  property :name
  property :email
end
# app/representers/comment_representer.rb
require 'roar/decorator'
require 'roar/json'
class CommentRepresenter < Roar::Decorator
  include Roar::JSON
  property :body
  property :user
end
# app/representers/article_representer.rb
require 'roar/decorator'
require 'roar/json'
class ArticleRepresenter < Roar::Decorator
  include Roar::JSON
  property :id
  property :title
  property :content
  property :author, decorator: AuthorRepresenter
  collection :comments, decorator: CommentRepresenter
end

From Rails console executes the following code to generate JSON data,

article = Article.first
ArticleRepresenter.new(article).to_hash
=> {"id"=>1, "title"=>"New Article", "content"=>"Article Content", "author"=>{"id"=>1, "name"=>"Anderson", "email"=>"anderson@gmail.com"}, "comments"=>[{"body"=>"comment", "user"=>"visitor"}]}

Also Read: 10 Useful Ruby On Rails Gems We Couldn’t Live Without

Fast JSON API

A lightning fast JSON:API serializer for Ruby Objects.
Add the following gem into your gemfile and run bundle install,

gem 'fast_jsonapi'

Since we have already created serializers so we just need to update our serializers now,

# app/serializers/author_serializer.rb
class AuthorSerializer
  include FastJsonapi::ObjectSerializer
  attributes :id, :name, :email
end
# app/serializers/article_serializer.rb
class ArticleSerializer
  include FastJsonapi::ObjectSerializer
  belongs_to :author
  has_many :comments
  attributes :id, :title, :content
end
# app/serializers/comment_serializer.rb
class CommentSerializer
  include FastJsonapi::ObjectSerializer
  attributes :id, :body, :user
end

From rails console execute the following code to prepare data for JSON,

article = Article.first
ArticleSerializer.new(article, include: [:author, :comments]).serializable_hash
=> {:data=>{:id=>"1", :type=>:article, :attributes=>{:id=>1, :title=>"New Article", :content=>"Article Content"}, :relationships=>{:author=>{:data=>{:id=>"1", :type=>:author}}, :comments=>{:data=>[{:id=>"1", :type=>:comment}]}}}, :included=>[{:id=>"1", :type=>:author, :attributes=>{:id=>1, :name=>"Anderson", :email=>"anderson@gmail.com"}}, {:id=>"1", :type=>:comment, :attributes=>{:id=>1, :body=>"comment", :user=>"visitor"}}]}

JSONAPI::Serializers

JSONAPI::Serializers is a simple library for serializing Ruby objects and their relationships into the JSON:API format.
Add the following gem into our gemfile and run bundle install,

gem 'jsonapi-serializers'

Now we can update our serializers to use JSONAPI::Serializers like following,

# app/serializers/author_serializer.rb
class AuthorSerializer
  include JSONAPI::Serializer
  attributes :id, :name, :email
end
# app/serializers/article_serializer.rb
class ArticleSerializer
  include JSONAPI::Serializer
  has_one :author
  has_many :comments
  attributes :id, :title, :content
end
# app/serializers/comment_serializer.rb
class CommentSerializer
  include JSONAPI::Serializer
  attributes :id, :body, :user
end

From rails console execute the following code to prepare data for json,

article = Article.first
JSONAPI::Serializer.serialize(article, include: ['author', 'comments'])
=> {"data"=>{"type"=>"articles", "id"=>"1", "attributes"=>{"id"=>1, "title"=>"New Article", "content"=>"Article Content"}, "links"=>{"self"=>"/articles/1"}, "relationships"=>{"author"=>{"links"=>{"self"=>"/articles/1/relationships/author", "related"=>"/articles/1/author"}, "data"=>{"type"=>"authors", "id"=>"1"}}, "comments"=>{"links"=>{"self"=>"/articles/1/relationships/comments", "related"=>"/articles/1/comments"}, "data"=>[{"type"=>"comments", "id"=>"1"}]}}}, "included"=>[{"type"=>"authors", "id"=>"1", "attributes"=>{"id"=>1, "name"=>"Anderson", "email"=>"anderson@gmail.com"}, "links"=>{"self"=>"/authors/1"}}, {"type"=>"comments", "id"=>"1", "attributes"=>{"id"=>1, "body"=>"comment", "user"=>"visitor"}, "links"=>{"self"=>"/comments/1"}}]}

RABL

RABL (Ruby API Builder Language) is a ruby templating system for generating JSON.
Now add the following gem into our gemfile and run bundle install.

gem 'rabl'

Create the json template under app/views

# app/views/author.rabl
object @author
attribute :id, :name, :email
# app/views/article.rabl
object @article
attributes :id, :title, :content
child :author do
  extends "author"
end
child :comments do
  extends "comment"
end
# app/views/comment.rabl
object @comment
attributes :id, :user, :body

Execute the following code from rails console to prepare json data

Rabl.render(article, 'article', :view_path => 'app/views', :format => :hash)
=> {:id=>1, :title=>"New Article", :content=>"Article Content", :author=>{:id=>1, :name=>"Anderson", :email=>"anderson@gmail.com"}, :comments=>[{:id=>1, :user=>"visitor", :body=>"comment"}]}

JSONAPI::Resources

JSONAPI::Resources is focused on the resources served by an API, To know more about JSONAPI::Resources check here http://jsonapi-resources.com/
Add the following gem into your gemfile and run bundle install

gem 'jsonapi-resources'

after bundle install, use the following comment to generate the resources.

rails generate jsonapi:resource article
rails generate jsonapi:resource author
rails generate jsonapi:resource comment

You could see our generated resources in the app/resources directory

# app/resources/author_resource.rb
class AuthorResource < JSONAPI::Resource
  attributes :name, :email
end
# app/resources/article_resource.rb
class ArticleResource < JSONAPI::Resource
  has_one :author
  has_many :comments
  attributes :title, :content
end
# app/resources/comment_resource.rb
class CommentResource < JSONAPI::Resource
  attributes :body, :user
end

Start executing the following code from rails console to prepare json data,

article = Article.first
JSONAPI::ResourceSerializer.new(ArticleResource, include: ['author', 'comments']).serialize_to_hash(ArticleResource.new(article, nil))
 => {:data=>{"id"=>"1", "type"=>"articles", "links"=>{:self=>"/articles/1"}, "attributes"=>{"title"=>"New Article", "content"=>"Article Content"}, "relationships"=>{"author"=>{:links=>{:self=>"/articles/1/relationships/author", :related=>"/articles/1/author"}, :data=>{:type=>"authors", :id=>"1"}}, "comments"=>{:links=>{:self=>"/articles/1/relationships/comments", :related=>"/articles/1/comments"}, :data=>[{:type=>"comments", :id=>"1"}]}}}, :included=>[{"id"=>"1", "type"=>"authors", "links"=>{:self=>"/authors/1"}, "attributes"=>{"name"=>"Anderson", "email"=>"anderson@gmail.com"}}, {"id"=>"1", "type"=>"comments", "links"=>{:self=>"/comments/1"}, "attributes"=>{"body"=>"comment", "user"=>"visitor"}}]}

Data Transformation

Data transformation is the process of converting or transforming hash into JSON format. A set of rich complement built-in operators and functions is provided for manipulating and combining extracted data.

JSON

Ruby provides JSON as a default standard serialization library and we can directly use it in our rails console to convert the hash into a JSON format.

author = {:name => "Anderson", :email => "anderson@gmail.com"}
JSON.generate(author)
=> "{\"name\":\"Anderson\",\"email\":\"anderson@gmail.com\"}"

Oj

Oj is a fast JSON parser and Object marshaller as a Ruby gem. Add the following gem into your gemfile, and run bundle installs.

gem 'oj'

Execute following code into rails console to convert the hash into JSON format,

author = {:name => "Anderson", :email => "anderson@gmail.com"}
Oj.dump(author)
=> "{\":name\":\"Anderson\",\":email\":\"anderson@gmail.com\"}"

YAJL

Yajl is JSON parsing and encoding directly to and from a stream or String. This will Parse and encode multiple JSON objects to and from streams or strings continuously. Add the following gem into your gemfile, and run bundle install.

gem 'yajl-ruby'

Execute following code into rails console to convert the hash into json format,

require 'yajl'
author = {:name => "Anderson", :email => "anderson@gmail.com"}
Yajl::Encoder.encode(author)
=> "{\"name\":\"Anderson\",\"email\":\"anderson@gmail.com\"}"

On finalizing how fast is each library, i have used Ruby Benchmark to compare data preparation and transformation time for each tool to check. Here i have used 30 articles with author and each article will have 50 comments.

S. No. Tool Name Time Taken
1 Fast JSON API 0.181660
2 ROAR 0.217807
3 JSONAPI::Serializers 0.273731
4 JSONAPI-RB 0.285836
5 Active Model Serializers 0.293275
6 Jbuilder 0.413474
7 JSONAPI::Resources 0.421009
8 RABL 0.656725

 

S.No Toll Name Time Taken
1 Oj 0.006654
2 Yajl 0.011478
3 JSON 0.042426

I have listed down the libraries and placed it based on its performance so how fast it is and as a top, it would be. On the go, you could also see the precise and collaborative results for each library along with its serving speed. On the other hand, we respect your suggestions! Run your benchmark test and share your results with us. We appreciate your valuable feedbacks and improvements.
Hope this helps you! and if you also wish to explore more about technologies then join us on the excursion of exploring Technologies subscribe to us to get more blogs & updates on the latest technologies. Agira Technologies one of the leading Web and Mobile Development companies in India. Precisely, extends its research on Web technologies, Mobile Apps, Blockchain, Chatbot, Artificial Intelligence, IoT and a lot more.
For any inquiries reach us at info@agiratech.com

Turn your vision to magnificent reality With
Our Web and Mobile Solutions

Arjunan Subramani

Senior Software Engineer | Around 4 Years of experience in Web development and Testing arena. Plus, hands on expertise in Ruby, Ruby on Rails, Watir, Ruby Cucumber.