Customization Options
This guide covers various ways to customize the serialization output in Ruby JSONAPI.
Serializer Options Reference
The following table describes all customization options available for serializers:
Option | Purpose | Example |
---|---|---|
set_type | Type name of Object | set_type :movie |
key | Key of Object | belongs_to :owner, key: :user |
set_id | ID of Object | set_id :owner_id or set_id { |record, params| params[:admin] ? record.id : "#{record.name.downcase}-#{record.id}" } |
cache_options | Hash with store to enable caching and optional further cache options | cache_options store: ActiveSupport::Cache::MemoryStore.new, expires_in: 5.minutes |
id_method_name | Set custom method name to get ID of an object (If block is provided for the relationship, id_method_name is invoked on the return value of the block instead of the resource object) | has_many :locations, id_method_name: :place_ids |
object_method_name | Set custom method name to get related objects | has_many :locations, object_method_name: :places |
record_type | Set custom Object Type for a relationship | belongs_to :owner, record_type: :user |
serializer | Set custom Serializer for a relationship | has_many :actors, serializer: :custom_actor , has_many :actors, serializer: MyApp::Api::V1::ActorSerializer , or has_many :actors, serializer: -> (object, params) { (return a serializer class) } |
polymorphic | Allows different record types for a polymorphic association | has_many :targets, polymorphic: true |
polymorphic | Sets custom record types for each object class in a polymorphic association | has_many :targets, polymorphic: { Person => :person, Group => :group } |
Key Transforms
Ruby JSONAPI supports different key transformation options for the attribute names in the serialized output.
Available Key Transforms
:camel
-first_name
becomesFirstName
:camel_lower
-first_name
becomesfirstName
:dash
-first_name
becomesfirst-name
:underscore
-firstName
becomesfirst_name
Setting Key Transform
class MovieSerializer
include JSONAPI::Serializer
set_key_transform :camel_lower
attributes :first_name, :last_name
end
Conditional Attributes
You can conditionally include attributes:
class MovieSerializer
include JSONAPI::Serializer
attributes :name, :year
# Include budget only if condition is met
attribute :budget, if: Proc.new { |movie| movie.public_budget? }
# Include revenue only for admin users
attribute :revenue, if: Proc.new { |movie, params|
params && params[:admin] == true
}
end
When using this feature:
# Normal serialization (revenue not included)
serializer = MovieSerializer.new(movie)
# Admin serialization (revenue included)
serializer = MovieSerializer.new(movie, { params: { admin: true } })
Dynamic Attributes
You can define attributes that compute their values dynamically:
class MovieSerializer
include JSONAPI::Serializer
attributes :name, :year
# Computed attribute
attribute :full_title do |movie|
"#{movie.name} (#{movie.year})"
end
# Using params
attribute :director_info do |movie, params|
if params && params[:detailed]
"#{movie.director.name} (#{movie.director.nationality})"
else
movie.director.name
end
end
end
Custom Attribute Blocks
For more complex attribute logic, you can use blocks:
class MovieSerializer
include JSONAPI::Serializer
attributes :name, :year
attribute :rating do |movie|
if movie.ratings.any?
(movie.ratings.sum / movie.ratings.size.to_f).round(1)
else
nil
end
end
end
Global Meta Information
You can add metadata to all your serializers:
JSONAPI::Serializer.configure do |config|
config.meta = ->() { { api_version: '1.0' } }
end
Custom Links
You can add custom links to your serialized resources:
class MovieSerializer
include JSONAPI::Serializer
attributes :name, :year
link(:self) { |movie| "/movies/#{movie.id}" }
link(:related) { |movie| "/related-movies/#{movie.genre}" }
end
Output:
{
"data": {
"id": "1",
"type": "movie",
"attributes": { "name": "Inception", "year": 2010 },
"links": {
"self": "/movies/1",
"related": "/related-movies/sci-fi"
}
}
}
Resource-Level Meta
You can add meta information to individual resources:
class MovieSerializer
include JSONAPI::Serializer
attributes :name, :year
meta do |movie|
{
years_since_release: Time.current.year - movie.year
}
end
end
This produces:
{
"data": {
"id": "1",
"type": "movie",
"attributes": { "name": "Inception", "year": 2010 },
"meta": {
"years_since_release": 15
}
}
}
Custom ID Method
You can specify how IDs are derived:
class MovieSerializer
include JSONAPI::Serializer
# Use a custom method to get the ID
set_id :slug
# Or with a block for more complex logic
set_id do |movie, params|
params && params[:admin] ? movie.id : movie.slug
end
attributes :name, :year
end
Next Steps
Now that you understand customization options, check out advanced features like caching and sparse fieldsets.