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