Rails - JSONの解説とjbuilderでのAPI構築
はじめに
本記事では「パーフェクト Ruby on Rails」で学んだ内容と別途気になって調べた内容や知識も含めアウトプットしています。
書籍に記載されている内容を順序立ててまとめるというよりは、整理しておきたい周辺の知識と深ぼった内容を雑多に書いています。
Rails APIでJSONを返す
Railsではrenderメソッドなどを使用してビューのHTMLテンプレートを生成して返すこともできますが、APIサーバとして機能させ、JSON形式でのレスポンスを返すことも可能です。
Railsでは、簡単にJSONレスポンスを生成できる仕組みが用意されています。
JSONの構築
renderメソッド呼び出し時にJSONへオブジェクトを変換することができますが、より複雑なJSONデータを構築する場合は、HTMLテンプレートのようにJSONデータを構築する方法ができ、APIとして使用する場合はこの方法が一般的です。
jbuilder
Railsでは、Active Model SerializersやJbuilderといったGemを使用して、JSONデータを構築することができます。
これらのGemを使用すると、宣言的に複雑なJSONレスポンスを作成することができます。
拡張子
Jbuilderで整形されたJSONデータを構築するためのファイルの拡張子は、.json.jbuilder
です。この拡張子は、RailsによってJbuilderテンプレートとして認識されます。
コード例
app/controllers/api/v1/users_controller.rb
リクエストによってApi::V1::Settings::UsersController
のindex
アクション内の処理が実行され、@users
に適切なデータが設定されたあとビューレンダリングのフェーズに入ります。
# app/controllers/api/v1/users_controller.rb class Api::V1::UsersController < Api::Base::ApplicationController skip_before_action :authenticate! def index @users = User.all end end
app/views/api/v1/users/index.json.jbuilder
Railsは自動的にビューファイルを探し、適切なJbuilderテンプレートを特定します。
デフォルトの検索パスは、app/views
ディレクトリ内のコントローラーに対応するサブディレクトリです。
この場合、app/views/api/v1/users/index.json.jbuilder
がJbuilderテンプレートとしての候補となります。
# app/views/api/v1/users/index.json.jbuilder if @user.blank? json.status :error json.message I18n.t("errors.no_data") else json.status :success json.set! :data do json.(@user.decorate, :name, :email) if @user.plan.present? json.plan do json.id @user.plan.id json.name @user.plan.name end end end end end
特定されたJbuilderテンプレートが読み込まれ、コントローラー内で定義されたインスタンス変数やローカル変数を使用して、JSONデータの構築が行われます。
Jbuilderテンプレート内で定義されたJSONデータの構築処理が完了し、レスポンスとして返されます。
上記の流れにより、index
アクションに対応するJbuilderテンプレートが特定され、コントローラー内で設定された変数を使用してJSONデータが構築され、最終的にJSONデータがレスポンスとしてクライアントに返されます。
部分テンプレート
jsonもerbと同様に部分テンプレートも使用することができます。
app/views/api/v1/users/_user.json.jbuilder
ユーザー情報を含む部分テンプレート _user.json.jbuilder
を作成します。
json.(@user.decorate, :name, :email)
上記のテンプレートでは、@user
オブジェクトのname
とemail
属性をJSONに追加しています。
app/views/api/v1/users/index.json.jbuilder
元のテンプレートである app/views/api/v1/plans/index.json.jbuilder
を以下のように修正します。
json.partial!
メソッドを使用して、部分テンプレート _user.json.jbuilder
を読み込んでいます。引数として user: @user
を渡しています。
if @user.blank? json.status :error json.message I18n.t("errors.no_data") else json.status :success json.set! :data do json.partial! 'api/v1/plans/user', user: @user if @user.plan.present? json.plan do json.id @user.plan.id json.name @user.plan.name end end end end
解説
json.partial!
の第1引数は、部分テンプレートのパスを指定します。
'api/v1/plans/user'
と指定することで、_user.json.jbuilder
を参照します。
json.partial!
の第2引数は、部分テンプレート内で使われる変数を指定します。ここでは user: @user
を渡しているので、部分テンプレート内では user
としてアクセスできます。
index.json.jbuilder
では部分テンプレート _user.json.jbuilder
を使用して、ユーザー情報を含むJSONデータが構築されます。
部分テンプレートを利用することで、同じユーザー情報のJSONデータを複数のテンプレートで再利用することができ、部分テンプレートを使うことでコードの可読性や保守性も向上します。
参考
続く…
コメント
本記事の内容は以上になります!
書籍の続きのアウトプットも随時更新したいと思います。
プログラミングスクールのご紹介 (卒業生より)
お世話になったプログラミングスクールであるRUNTEQです♪
こちらのリンクを経由すると1万円引きになります。
RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。
もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。