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
end
Now 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
end
By 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
end
Here 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
Here is a list of hooks that allow you to defined controller level defaults for your serializer options
serializer option | hook |
---|---|
params | jsonapi_serializer_params |
meta | jsonapi_meta |
links | jsonapi_links |
fields | jsonapi_fields |
include | jsonapi_include |
class UserController < ActionController::Base
# jsonapi_meta hook is called
def index_1
render jsonapi: @user
end
# by default jsonapi_meta hook is not called when its option is defined at
# the action level. Use force_jsonapi_hooks: true to force call
def index_2
render jsonapi: @user, { meta: {some_key: 'test'} }
end
private
def jsonapi_meta(resource, meta = {})
meta[:total] = resource.count if resource.respond_to?(:count)
meta
end
end
If you want to skip the default hooks on a specific controller 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.