Skip to content

skarmakar/fast-json-serializer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fast::Json::Serializer

This gem generates the JSON bypassing ActiveRecord object creation, which make JSON generation blazing fast! It uses ActiveRecord::Base.connection.execute method which returns PG::Result. JSON is generated by iterating over the collection.

Installation

Add this line to your application's Gemfile:

gem 'fast-json-serializer'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install fast-json-serializer

Usage

Create a app/serializers/application_serializer.rb with the following code:

# app/serializers/application_serializer.rb

require 'fast/json/serializer/base'

class ApplicationSerializer < Fast::Json::Serializer::Base
end

Make the other serializers a subclass of the ApplicationSerializer class

# app/serializers/post_serializer.rb

class PostSerializer < ApplicationSerializer
  # enable FastJsonapi format by uncommenting this line
  # set_type :post

  attributes :id, :title, :creator_name, :creator_email

  # use a ruby/rails formatter
  attribute :created_at, format: :to_s
  attribute :updated_at, format: :to_s

  # rename the json key name
  attribute :created_at_epoch, column_name: :created_at, format: :to_i
  attribute :updated_at_epoch, column_name: :updated_at, format: :to_i

  # use custom method
  attribute :created_at_ist do |serializer, hash|
    serializer.ist_time(hash['created_at'])
  end

  attribute :updated_at_ist do |serializer, hash|
    serializer.ist_time(hash['updated_at'])
  end

  # a class method can be used as well 
  def ist_time(timestamp)
    return unless timestamp
    
    timestamp.in_time_zone("Kolkata").strftime('%A - %b %d, %Y')
  end
end

Formatting of the JSON

Currently, it supports two formats, key-value, and FastJsonapi format

PostSerializer.new(Post.limit(10)).serialized_json

produces, with set_type :post enabled:

{
  "data": [
    {
      "id": 1,
      "type": "post",
      "attributes": {
        "id": 1,
        "title": "Tacos",
        "creator_name": "Ella Erdman",
        "creator_email": "sean.zieme@smitham.name",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 2,
      "type": "post",
      "attributes": {
        "id": 2,
        "title": "Barbecue Ribs",
        "creator_name": "Mrs. Fern Yundt",
        "creator_email": "rafael.simonis@metz.com",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 69,
      "type": "post",
      "attributes": {
        "id": 69,
        "title": "French Fries with Sausages",
        "creator_name": "Vance Connelly",
        "creator_email": "leslee_langosh@mann.biz",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 3,
      "type": "post",
      "attributes": {
        "id": 3,
        "title": "Pork Belly Buns",
        "creator_name": "Mrs. Willie Green",
        "creator_email": "aracely_tromp@torphy-jenkins.info",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 4,
      "type": "post",
      "attributes": {
        "id": 4,
        "title": "Peking Duck",
        "creator_name": "Joselyn VonRueden",
        "creator_email": "marianna_damore@lehner-metz.org",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 5,
      "type": "post",
      "attributes": {
        "id": 5,
        "title": "Hummus",
        "creator_name": "Stacee Pfannerstill",
        "creator_email": "barrett_johnston@weimann-gottlieb.name",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 6,
      "type": "post",
      "attributes": {
        "id": 6,
        "title": "California Maki",
        "creator_name": "Fidel Schroeder",
        "creator_email": "marquitta@kuvalis.info",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 7,
      "type": "post",
      "attributes": {
        "id": 7,
        "title": "French Toast",
        "creator_name": "Alvaro Berge",
        "creator_email": "randal_littel@fadel-fritsch.io",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 8,
      "type": "post",
      "attributes": {
        "id": 8,
        "title": "Arepas",
        "creator_name": "Alva Kris DO",
        "creator_email": "nathaniel_strosin@wintheiser.net",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    },
    {
      "id": 9,
      "type": "post",
      "attributes": {
        "id": 9,
        "title": "Meatballs with Sauce",
        "creator_name": "Willie Kuhic",
        "creator_email": "paul.rowe@mraz.biz",
        "created_at": "2022-10-13 05:51:08 UTC",
        "updated_at": "2022-10-13 05:51:08 UTC",
        "created_at_epoch": 1665640268,
        "updated_at_epoch": 1665640268,
        "created_at_ist": "Thursday - Oct 13, 2022",
        "updated_at_ist": "Thursday - Oct 13, 2022"
      }
    }
  ]
}

and with set_type :post disabled

[
  {
    "id": 1,
    "title": "Tacos",
    "creator_name": "Ella Erdman",
    "creator_email": "sean.zieme@smitham.name",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 2,
    "title": "Barbecue Ribs",
    "creator_name": "Mrs. Fern Yundt",
    "creator_email": "rafael.simonis@metz.com",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 69,
    "title": "French Fries with Sausages",
    "creator_name": "Vance Connelly",
    "creator_email": "leslee_langosh@mann.biz",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 3,
    "title": "Pork Belly Buns",
    "creator_name": "Mrs. Willie Green",
    "creator_email": "aracely_tromp@torphy-jenkins.info",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 4,
    "title": "Peking Duck",
    "creator_name": "Joselyn VonRueden",
    "creator_email": "marianna_damore@lehner-metz.org",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 5,
    "title": "Hummus",
    "creator_name": "Stacee Pfannerstill",
    "creator_email": "barrett_johnston@weimann-gottlieb.name",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 6,
    "title": "California Maki",
    "creator_name": "Fidel Schroeder",
    "creator_email": "marquitta@kuvalis.info",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 7,
    "title": "French Toast",
    "creator_name": "Alvaro Berge",
    "creator_email": "randal_littel@fadel-fritsch.io",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 8,
    "title": "Arepas",
    "creator_name": "Alva Kris DO",
    "creator_email": "nathaniel_strosin@wintheiser.net",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  },
  {
    "id": 9,
    "title": "Meatballs with Sauce",
    "creator_name": "Willie Kuhic",
    "creator_email": "paul.rowe@mraz.biz",
    "created_at": "2022-10-13 05:51:08 UTC",
    "updated_at": "2022-10-13 05:51:08 UTC",
    "created_at_epoch": 1665640268,
    "updated_at_epoch": 1665640268,
    "created_at_ist": "Thursday - Oct 13, 2022",
    "updated_at_ist": "Thursday - Oct 13, 2022"
  }
]

Benchmark, rails 7.0.2.3, ruby 3.0.3

  # there are 1100 posts in the DB, having fields 
  # :id, :title, :content, :creator_name, :creator_email, :created_at, :updated_at
  posts = Post.all
  s = PostSerializer.new(posts)

  n = 1000
  Benchmark.bm do |x|
    x.report("ActiveModel Serializer") { n.times { posts.to_json } }
    x.report("JSON:API Serialization") { n.times { PostJsonapiSerializer.new(posts).serializable_hash.to_json }}
    x.report("Blueprinter")            { n.times { PostBlueprint.render(posts) }}
    x.report("FastJsonSerializer")     { n.times { s.serialized_json } }
  end

  # result
  user                    system      total         real
  ActiveModel Serializer  35.373407   0.000000      35.373407 ( 35.380744)
  JSON:API Serialization  50.476935   0.043584      50.520519 ( 50.546082)
  Blueprinter             20.458713   0.000000      20.458713 ( 20.484488)
  FastJsonSerializer       5.239119   0.015989       5.255108 (  5.256627)

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/skarmakar/fast-json-serializer.

About

Ruby fast JSON serializer

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published