Here are some codes to help you build your next JSON:API compliable application easier and faster.
- Uncomment and test
RailsJSONAPI::MediaTypeFilter, add to theRailsJSONAPI::Rails::Railtie#initializer
It's quite a hassle to setup a Ruby (Rails) web application to use and follow the JSON:API specifications.
The idea is simple, JSONAPI.rb offers an easy way to confiture your application with code that contains no magic and with little code!
The available features include:
- jsonapi renderer (powered by Fast JSON API)
- sparse fields
- includes
- jsonapi_errors renderer
- error handling in controller
- error serializers
- generic
- active model
- deserialization (with support for nested deserialization and local-id!)
Mainly by leveraging Fast JSON API and jsonapi-deserializable Thanks to everyone who worked on these amazing projects!
Add this line to your application's Gemfile:
gem 'jsonapi.rb'And then execute:
$ bundle
Or install it yourself as:
$ gem install jsonapi.rb
This gem contains a Rails::Railtie that will:
- register the jsonapi mime type 'application/vnd.api+json'
- register a parameter parser that will nest jsonapi request params under the key raw_jsonapi
- register a jsonapi renderer to controllers
- register a jsonapi_errors renderer to controllers
Assuming you have a model
class User < ActiveRecord::Base
#local id sent by API client, optional
attr_accessor :lid
endNow lets define our first serializer and deserializer
see Fast JSON API guide on how to define a serializer.
# app/serializers/user_serializer.rb
class UserSerializer
include FastJsonapi::ObjectSerializer
end# app/deserializers/user_deserializer.rb
class UserDeserializer < JSONAPI::Deserializable::Resource
type
id
attributes
endBy default, a serializer class will be guessed when using thejsonapi renderer depending on the class of the resource to be rendered. If the resource is a collection, it will use the item's class. An instance of ClassName will resolve a ClassNameSerializer serializer
You can also specify which serializer to use at a controller level by implementing the jsonapi_serializer_class hook method or by passing the serializer_class option.
Here's an example:
class UserController < ActionController::Base
# ...
# override at action level with serializer_class
def show
# ...
render jsonapi: @user, {serializer_class: OtherSerializer}
end
private
# controller level hook
def jsonapi_serializer_class(resource, is_collection)
YourCustomSerializer
end
endHere is the list of common options you can pass to the jsonapi renderer:
- is_collection
- serializer_class
It also supports any other options or params to be passed to the serializer
You can use default_jsonapi_options to define default options that will be passed to the renderer.
class UserController < ActionController::Base
# meta will be set from `default_jsonapi_options`
def index_1
render jsonapi: @user
end
# if a `meta` was passed directly to the `render`, the meta returned from default_jsonapi_options will be ignored. You'll need to merge them manually with the `options` argument passed to `default_jsonapi_options`
def index_2
render jsonapi: @user, meta: {some_key: 'test'}
end
private
def default_jsonapi_options(_resource, _options)
case action_name
when 'index_1', 'index_2'
{
meta: {
total: resource.count
}
}
end
end
endIf you want to skip default_jsonapi_options on a specific action you can use the skip_jsonapi_hooks option
includint RailsJSONAPI::Controller::Utils into your controller will give you access to
- jsonapi_include_param
- jsonapi_fields_param
The gem is available as open source under the terms of the MIT License.