先日OpenAPIのスキーマからRubyのクラスを自動生成するgemを作りました。
OpenAPIのschema定義からRubyのクラスを生成するgem「openapi2ruby」をつくりました - Start Today Technologies TECH BLOG
このgemを作って自動生成しようとしたのがActiveModel::Serializer(AMS)のシリアライザで
他にも自動生成できるものがないか調べていたときに、ちょっと前に話題になったNetflixのgemを見つけたので使ってみることに。
なんでも
serialization time is at least 25 times faster than Active Model Serializers on up to current benchmark of 1000 records.
らしい。速い。
サンプルアプリケーション作成
# Gemfile gem 'fast_jsonapi'
先述の会社ブログのサンプルにならい User has_one Profile
なモデルを持つRailsアプリを作成。
User.name
, Profile.description
なフィールドをそれぞれ持つ。
# user.rb class User < ApplicationRecord has_one :profile end # profile.rb class Profile < ApplicationRecord belongs_to :user end
それぞれに対応するシリアライザを作成
# user_serializer.rb class UserSerializer include FastJsonapi::ObjectSerializer has_one :profile, serializer: ProfileSerializer attributes :name # カスタムattributeの定義も可能 attributes :name_with_id do |object| "#{object.id}: #{object.name}" end end # profile_serializer.rb class ProfileSerializer include FastJsonapi::ObjectSerializer belongs_to :user, serializer: UserSerializer attributes :description end
最後にControllerから呼び出す
# users_controller.rb class UsersController < ApplicationController def show user = User.find(params[:id]) options = { include: [:profile] } serializer = UserSerializer.new(user, options) render json: serializer.serialized_json end end
ブラウザでアクセスすると...
{ "data": { "id": "1", "type": "user", "attributes": { "name": "takanamito", "name_with_id": "1: takanamito" }, "relationships": { "profile": { "data": { "id": "1", "type": "profile" } } } }, "included": [ { "id": "1", "type": "profile", "attributes": { "description": "プロフィールです" }, "relationships": { "user": { "data": { "id": "1", "type": "user" } } } } ] }
所感
サンプルでも触れたCustom Attributesがブロックで簡単に書けたり
Conditional Attributes、Conditional Relationshipsなど便利機能も多くて助かる。
AMSと大きく異なる点が、READMEに書かれてる通り
デフォルトで生成するのがJSON:APIに準拠したjsonなところ。
シリアライズするオブジェクトに id
, type
というフィールドが必須だったり、いくつか制約がある模様。
ActiveRecordのオブジェクトをシリアライズするのはいいが、プレーンなRubyオブジェクトをシリアライズするときに id
相当のものが無くて困る。
気になってAMSのREADMEも読んでみると、どうやら開発中のバージョン1.0ではAMSでもJSON:APIに準拠するシリアライザになるとのこと。
The serializer will essentially be for defining a basic JSON:API resource object: id, type, attributes, and relationships.
GitHub - rails-api/active_model_serializers: ActiveModel::Serializer implementation and Rails hooks