Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
J

jsonapi-serializer

> 编程语言
Open source

A fast JSON:API serializer for Ruby (fork of Netflix/fast_jsonapi)

1.4K stars0 likes0 views
WebsiteGitHub

About

A fast JSON:API serializer for Ruby (fork of Netflix/fast_jsonapi)

JSON:API Serialization Library

:warning: :construction: v2 (the master branch) is in maintenance mode! :construction: :warning:

We'll gladly accept bugfixes and security-related fixes for v2 (the master branch), but at this stage, contributions for new features/improvements are welcome only for v3. Please feel free to leave comments in the v3 Pull Request.


A fast JSON:API serializer for Ruby Objects.

Previously this project was called fast_jsonapi, we forked the project and renamed it to jsonapi/serializer in order to keep it alive.

We would like to thank the Netflix team for the initial work and to all our contributors and users for the continuous support!

Performance Comparison

We compare serialization times with ActiveModelSerializer and alternative implementations as part of performance tests available at jsonapi-serializer/comparisons.

We want to ensure that with every change on this library, serialization time stays significantly faster than the performance provided by the alternatives. Please read the performance article in the docs folder for any questions related to methodology.

Table of Contents

  • Features
  • Installation
  • Usage
    • Rails Generator
    • Model Definition
    • Serializer Definition
    • Object Serialization
    • Compound Document
    • Key Transforms
    • Collection Serialization
    • Caching
    • Params
    • Conditional Attributes
    • Conditional Relationships
    • Specifying a Relationship Serializer
    • Ordering has_many Relationship
    • Sparse Fieldsets
    • Using helper methods
  • Performance Instrumentation
  • Deserialization
  • Migrating from Netflix/fast_jsonapi
  • Contributing

Features

  • Declaration syntax similar to Active Model Serializer
  • Support for belongs_to, has_many and has_one
  • Support for compound documents (included)
  • Optimized serialization of compound documents
  • Caching

Installation

Add this line to your application's Gemfile:

ruby
gem 'jsonapi-serializer'

Execute:

bash
$ bundle install

Usage

Rails Generator

You can use the bundled generator if you are using the library inside of a Rails project:

rails g serializer Movie name year

This will create a new serializer in app/serializers/movie_serializer.rb

Model Definition

ruby
class Movie
  attr_accessor :id, :name, :year, :actor_ids, :owner_id, :movie_type_id
end

Serializer Definition

ruby
class MovieSerializer
  include JSONAPI::Serializer

  set_type :movie  # optional
  set_id :owner_id # optional
  attributes :name, :year
  has_many :actors
  belongs_to :owner, record_type: :user
  belongs_to :movie_type
end

Sample Object

ruby
movie = Movie.new
movie.id = 232
movie.name = 'test movie'
movie.actor_ids = [1, 2, 3]
movie.owner_id = 3
movie.movie_type_id = 1
movie

movies =
  2.times.map do |i|
    m = Movie.new
    m.id = i + 1
    m.name = "test movie #{i}"
    m.actor_ids = [1, 2, 3]
    m.owner_id = 3
    m.movie_type_id = 1
    m
  end

Object Serialization

Return a hash

ruby
hash = MovieSerializer.new(movie).serializable_hash

Return Serialized JSON

ruby
json_string = MovieSerializer.new(movie).serializable_hash.to_json

Serialized Output

json
{
  "data": {
    "id": "3",
    "type": "movie",
    "attributes": {
      "name": "test movie",
      "year": null
    },
    "relationships": {
      "actors": {
        "data": [
          {
            "id": "1",
            "type": "actor"
          },
          {
            "id": "2",
            "type": "actor"
          }
        ]
      },
      "owner": {
        "data": {
          "id": "3",
          "type": "user"
        }
      }
    }
  }
}

The Optionality of set_type

By default fast_jsonapi will try to figure the type based on the name of the serializer class. For example class MovieSerializer will automatically have a type of :movie. If your serializer class name does not follow this format, you have to manually state the set_type at the serializer.

Key Transforms

By default fast_jsonapi underscores the key names. It supports the same key transforms that are supported by AMS. Here is the syntax of specifying a key transform

ruby
class MovieSerializer
  include JSONAPI::Serializer

  # Available options :camel, :camel_lower, :dash, :underscore(default)
  set_key_transform :camel
end

Here are examples of how these options transform the keys

ruby
set_key_transform :camel # "some_key" => "SomeKey"
set_key_transform :camel_lower # "some_key" => "someKey"
set_key_transform :dash # "some_key" => "some-key"
set_key_transform :underscore # "some_key" => "some_key"

Attributes

Attributes are defined using the attributes method. This method is also aliased as attribute, which is useful when defining a single attribute.

By default, attributes are read directly from the model property of the same name. In this example, name is expected to be a property of the object being serialized:

ruby
class MovieSerializer
  include JSONAPI::Serializer

  attribute :name
end

Custom attributes that must be serialized but do not exist on the model can be declared using Ruby block syntax:

ruby
class MovieSerializer
  include JSONAPI::Serializer

  attributes :name, :year

  attribute :name_with_year do |object|
    "#{object.name} (#{object.year})"
  end
end

The block syntax can also be used to override the property on the object:

ruby
class MovieSerializer
  include JSONAPI::Serializer

  attribute :name do |object|
    "#{object.name} Part 2"
  end
end

Attributes can also use a different name by passing the original method or accessor with a proc shortcut:

ruby
class MovieSerializer
  include JSONAPI::Serializer

  attributes :name

  attribute :released_in_year, &:year
end

Links Per Object

Links are defined using the link method. By default, links are read directly from the model property of the same name. In this example, public_url is expected to be a property of the object being serialized.

You can configure the method to use on the object for example a link with key self will get set to the value returned by a method called url on the movie object.

You can also use a block to define a url as shown in custom_url. You can access params in these blocks as well as shown in personalized_url

ruby
class MovieSerializer
  include JSONAPI::Serializer

  link :public_url

  link :self, :url

  link :custom_url do |object|
    "https://movies.com/#{object.name}-(#{object.year})"
  end

  link :personalized_url do |object, params|
    "https://movies.com/#{object.name}-#{params[:user].reference_code}"
  end
end

Links on a Relationship

You can specify relationship links by using the links: option on the serializer. Relationship links in JSON API are useful if you want to load a parent document and then load associated documents later due to size constraints (see related resource links)

ruby
class MovieSerializer
  include JSONAPI::Serializer

  has_many :actors, links: {
    self: :url,
    related: -> (object) {
      "https://movies.com/#{object.id}/actors"
    }
  }
end

Relationship links can also be configured to be defined as a method on the object.

ruby
  has_many :actors, links: :actor_relationship_links

This will create a self reference for the relationship, and a related link for loading the actors relationship later. NB: This will not automatically disable loading the data in the relationship, you'll need to do that using the lazy_load_data option:

ruby
  has_many :actors, lazy_load_data: true, links: {
    self: :url,
    related: -> (object) {
      "https://movies.com/#{object.id}/actors"
    }
  }

Meta Per Resource

For every resource in the collection, you can include a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.

ruby
class MovieSerializer
  include JSONAPI::Serializer

  meta do |movie|
    {
      years_since_release: Date.current.year - movie.year
    }
  end
end

Meta on a Relationship

You can specify relationship meta by using the meta: option on the serializer. Relationship meta in JSON API is useful if you wish to provide non-standard meta-information about the relationship.

Meta can be defined either by passing a static hash or by using Proc to the meta key. In the latter case, the record and any params passed to the serializer are available inside the Proc as the first and second parameters, respectively.

ruby
class MovieSerializer
  include JSONAPI::Serializer

  has_many :actors, meta: Proc.new do |movie_record, params|
    { count: movie_record.actors.length }
  end
end

Compound Document

Support for top-level and nested included associations through options[:include].

ruby
options = {}
options[:meta] = { total: 2 }
options[:links] = {
  self: '...',
  next: '...',
  prev: '...'
}
options[:include] = [:actors, :'actors.agency', :'actors.agency.state']
MovieSerializer.new(movies, options).serializable_hash.to_json

Collection Serialization

ruby
options[:meta] = { total: 2 }
options[:links] = {
  self: '...',
  next: '...',
  prev: '...'
}
hash = MovieSerializer.new(movies, options).serializable_hash
json_string = MovieSerializer.new(movies, options).serializable_hash.to_json

Control Over Collection Serialization

You can use is_collection option to have better control over collection serialization.

If this option is not provided or nil autodetect logic is used to try understand if provided resource is a single object or collection.

Autodetect logic is compatible with most DB toolkits (ActiveRecord, Sequel, etc.) but cannot guarantee that single vs collection will be always detected properly.

ruby
options[:is_collection]

was introduced to be able to have precise control this behavior

  • nil or not provided: will try to autodetect single vs collection (please, see notes above)
  • true will always treat input resource as collection
  • false will always treat input resource as single object

Caching

To enable caching, use cache_options store: <cache_store>:

ruby
class MovieSerializer
  include JSONAPI::Serializer

  # use rails cache with a separate namespace and fixed expiry
  cache_options store: Rails.cache, namespace: 'jsonapi-serializer', expires_in: 1.hour
end

store is required can be anything that implements a #fetch(record, **options, &block) method:

  • record is the record that is currently serialized
  • options is everything that was passed to cache_options except store, so it can be everything the cache store supports
  • &block should be executed to fetch new data if cache is empty

So for the example above it will call the cache instance like this:

ruby
Rails.cache.fetch(record, namespace: 'jsonapi-serializer', expires_in: 1.hour) { ... }

Caching and Sparse Fieldsets

If caching is enabled and fields are provided to the serial

Issues· 66 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Ruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言