更新日:
【Rails】 JSON形式のデータを返却する方法とは?
Railsでは、renderメソッドを使って簡単にJSON形式のデータを返却することができます。
1
render json: オブジェクト
例えば、下記のように定義してhttp://localhost:3000/usersにアクセスすると、ハッシュで定義したユーザー情報がJSON形式のデータで返却されていることが分かります。
1
2
3
4
def index
users = { id:1, nickname: "ぴよっち", age: 22 }
render json: users
end
他にも、respond_toメソッドやgemを使ってJSON形式のデータを返却することができます。JSONがよくわからないという方は「ゼロから始めるJSON入門」を参考にしてください。
RailsでJSON形式のデータを返す方法
この章では、RailsでJSON形式のデータを返す方法を解説していきます。
renderメソッド
renderメソッドは、呼び出すテンプレート(ビュー)ファイルを指定するメソッドですが、オプションにjson
をつける事で、指定したオブジェクトをJSON形式のデータでレスポンスを返すことができます
1
render :json => オブジェクト
内部的には、指定したオブジェクトにto_jsonメソッドが使える場合は、このメソッドが呼び出されてオブジェクトをJSON形式のデータに変換しています。
また、ハッシュロケットを省略して下記のように定義する事もできます。
1
render json: オブジェクト
データベースのデータを使う
冒頭では、下記のようにrender
メソッドに渡すオブジェクト
をハッシュで定義しましたが、データベースのデータを使うこともできます。
1
2
3
4
def index
users = { id:1, nickname: "ぴよっち", age: 22 }
render json: users
end
データベースのデータは以下の通りです。
Userモデルのインスタンスをallメソッドで全て取得してrender
メソッドに渡します。
1
2
3
4
def index
@users = User.all
render json: @users
end
http://localhost:3000/usersにアクセスすると、下記のようにデータベースに保存されたデータをJSON形式のデータで返却する事が出来ています。
respond_toメソッド
respond_to
メソッドは、リクエストされたフォーマットによって処理を分ける事が出来るメソッドです。
下記のように定義すると、リクエストされるフォーマットがjson
だった場合は、{render :json => オブジェクト}
を返します。
1
2
3
4
respond_to |format|
format.html
format.json {render :json => オブジェクト}
end
また、リクエストされるフォーマットが指定されていない場合は、respond_to
メソッドを記述したアクションのデフォルトのテンプレートが返ります。
フォーマットの指定は、url
の最後に.json
とするとjson形式になって、.html
とするとhtml形式になります。
respond_toメソッドの詳細な使い方や処理の流れを知りたい方は、
こちらの「respond_toメソッドの使い方」を参考にしてください。
アプリケーションで確認しよう
アプリケーションで挙動を確認します。
今回は、usersコントローラのindexアクションにrespond_to
メソッドを記述するので、indexアクションのデフォルトのテンプレートは、app/views/users/index.html.erb
です。
このテンプレートには、以下のように記述します。
1
2
3
4
5
# filename: app/views/users/index.html.erb | ユーザー情報をJSON形式のデータで返却する
<p>
【ニックネーム】<%= @users[:nickname] %><br>
【年齢】<%= @users[:age] %>
</p>
usersコントローラのindexアクションには、以下のようにリクエストされるフォーマットがjson
だった場合は、JSON形式のデータが返却される様に定義します。
1
2
3
4
5
6
7
8
def index
@users = { id:1, nickname: "ぴよっち", age: 22 }
respond_to do |format|
format.html
format.json {render :json => @user}
end
end
フォーマットの指定をせずに、http://localhost:3000/usersにアクセスすると、
以下のようにデフォルトのテンプレートであるindexアクションのテンプレート(app/views/users/index.html.erb
)が表示されます。
そして、リクエストするフォーマットをjsonにしてhttp://localhost:3000/users.jsonにアクセスすると、下記の画像の様にJSON形式のデータが表示されます。
の方が良さそう。
この様に、respond_to
メソッドを使うことによって、リクエストされるフォーマットによって処理を分けることができます。
gem
これまでは、簡単なJSON形式のデータを返却する方法を解説してきましたが、より複雑なフォーマットで返す場合には、gemを利用します。
jbuilder
jbuilder
は、 Railsにデフォルトで備わっているgemです。
×××.json.jbuilder
のファイルをview
ディレクトリ配下に配置して、jbuilder
のイディオムに従って記述すると、JSON形式のデータを簡単に構築できます。
例えばindex.json.jbuilder
に対して、下記のように定義します。
1
json.text "テキスト"
http://localhost:3000/users.jsonにアクセスすると、上記の記述がJSON形式のデータに展開されています。
今回は簡単なJSON形式のデータを構築しましたが、インスタンスを使ったより複雑なフォーマットもjbuilder
で簡単に記述することができます。
詳しい使い方は、jbuilderの使い方辞典を参考にしてください。
ActiveModelSerializers
ActiveModelSerializers
は、jbuilder
よりもレスポンスが素早く直感的にコードを書く事が出来るgemです。
このgemを使うには、まずはGemfile
に下記を追加してbundle install
します。
1
gem 'active_model_serializers', '~> 0.10.0'
次に、rails g serializer モデル名
のコマンドを実行すると、app/serializers/モデル名_serializer.rb
にファイルが生成されます。今回は、ユーザー情報をJSON形式のデータで返却したいのでモデル名にuser
を指定します。
1
$ rails g serializer user
上記を実行すると、app/serializers/user_serializer.rb
に下記のファイルが生成されます。このファイルのattributes
には、JSON形式のデータで返したいプロパティを指定します。
例えば、下記のプロパティをJSONデータに含めたい場合は、
下記のように、:nickname, :age
を追加します。
1
2
3
class UserSerializer < ActiveModel::Serializer
attributes :id, :nickname, :age
end
そして、コントローラー(app/controllers/users_controller.rb
) のindexアクションに対して、下記のように記述します。
1
2
3
4
5
6
7
8
9
class UsersController < ApplicationController
def index
@users = User.all
render json: ActiveModel::Serializer::CollectionSerializer.new(
@users,
serializer: UserSerializer
).to_json
end
end
ActiveModel::Serializer::CollectionSerializer.new()
の第一引数には、Userモデルの全てのインスタンスを渡して、第二引数には使用するシリアライザーのクラス名(UserSerializer
)を渡します。
1
2
3
ActiveModel::Serializer::CollectionSerializer.new(リソース, serializer: 使用するシリアライザー名).to_json
# UsersController#index
ActiveModel::Serializer::CollectionSerializer.new(@users, serializer: UserSerializer).to_json
第一引数の@users
の要素を1つ1つ取り出してUserSerializer
に渡します。
1
2
3
class UserSerializer < ActiveModel::Serializer
attributes :id, :nickname, :age
end
http://localhost:3000/usersにアクセスすると、下記のように各ユーザーのid, nickname, age
がJSON形式のデータで返却されます。
公式ドキュメント:ActiveModelSerializers
RailsでJSON形式のデータを受け取る方法
JSON形式のデータが送られてきた場合に、Railsでは自動的にparamsに格納されるのでparams["キー名"]
でデータを取得できます。
例えば、下記のJSON形式のデータをPOST
でhttp://localhost:3000/usersへpostmanで送信した場合は、
下記のように、JSON形式の文字列で送信したデータがハッシュに自動変換されてparams
に格納されます。params["nickname"]
で値を取得できます。
1
2
3
4
5
6
# filename: コンソール | 送信されたデータの確認
[1] pry(#<UsersController>)> params
=> <ActionController::Parameters {"id"=>1, "nickname"=>"ぴよっち", "age"=>22, "controller"=>"users", "action"=>"create", "user"=>{"id"=>1, "nickname"=>"ぴよっち", "age"=>22}} permitted: false>
[2] pry(#<UsersController>)> params["nickname"]
=> "ぴよっち"
JSON形式の文字列を取得したい場合
Railsでは、送られてきたデータをparams
で取得できますが、送られてきたデータがJSON形式の文字列であった場合には、自動でハッシュに変換されます。
JSON形式の文字列をそのまま取得したい場合は、request.body.read
を使います。
1
2
3
# filename: コンソール | JSON形式の文字列を取得したい場合
[1] pry(#<UsersController>)> request.body.read
=> "{\n\t\"id\": 1, \n\t\"nickname\"ぴよっち",\n\t\"age\": 22\n}"
また、このJSON形式の文字列は、JSON.parseを使ってキー名をシンボルのハッシュに変換することもできます。
1
2
3
# filename: コンソール | キー名をシンボルのハッシュに変換する
[1] pry(#<UsersController>)> JSON.parse(request.body.read, symbolize_names: true)
=> {:id=>1, :nickname=>"ぴよっち", :age=>22}
このように、RailsではJSON形式の文字列のデータを簡単に受け取ることができます。他にも複数人で開発する方法など実践で必要な知識を学びたい方は、こちらの参考書もおすすめです。
この記事のまとめ
- Railsでは、
render
メソッドで簡単にJSON形式のデータを返却する事が出来る - 他にも、
respond_to
メソッドやjbuilder
やActiveModelSerializers
のgemを使ってJSON形式のデータを返却する事が出来る - また、JSON形式のデータが送られてきた場合は、paramsに格納されるので
params["キー名"]
でデータを取得する事が出来る