【Rails】JSON形式のデータを返却する方法とは?

Rails

Railsでは、renderメソッドを使って簡単にJSON形式のデータを返却する事が出来ます。

JSON形式のデータを返却する場合
1
render json:  オブジェクト

例えば、下記の様に定義してhttp://localhost:3000/usersにアクセスすると、ハッシュで定義したユーザー情報がJSON形式のデータで返却されている事が分かります。

app/controllers/users_controller.rb | ユーザー情報をJSON形式のデータで返却する
1
2
3
4
def index
    users = { id:1, nickname: "ぴよっち", age: 22 }
    render json: users
end

hashで定義した情報がJOSN形式のデータで返却される

他にも、respond_toメソッドやgemを使ってJSON形式のデータを返却する事が出来ます。

RailsでJSON形式のデータを返す方法

この章では、RailsでJSON形式のデータを返す方法を解説していきます。

renderメソッド
リンクをコピーしました

renderメソッドは、呼び出すテンプレート(ビュー)ファイルを指定するメソッドですが、オプションにjsonをつける事で、指定したオブジェクトをJSON形式のデータでレスポンスを返すことができます

JSON形式のデータを返却する場合
1
render :json => オブジェクト

内部的には、指定したオブジェクトにto_jsonメソッドが使える場合は、このメソッドが呼び出されてオブジェクトをJSON形式のデータに変換しています。

また、ハッシュロケットを省略して下記の様に定義する事もできます。

JSON形式のデータを返却する場合(ハッシュロケットを省略)
1
render json:  オブジェクト

データベースのデータを使う
リンクをコピーしました

冒頭では、下記の様にrenderメソッドに渡すオブジェクトハッシュで定義しましたが、データベースのデータを使う事も出来ます。

app/controllers/users_controller.rb | ユーザー情報をJSON形式のデータで返却する
1
2
3
4
def index
    users = { id:1, nickname: "ぴよっち", age: 22 }
    render json: users
end

データベースのデータは以下の通りです。

プロパティを確認

Userモデルのインスタンスをallメソッドで全て取得してrenderメソッドに渡します。

app/controllers/users_controller.rb | ユーザー情報をJSON形式のデータで返却する
1
2
3
4
def index
  @users = User.all
  render json: @users
end

http://localhost:3000/usersにアクセスすると、下記の様にデータベースに保存されたデータをJSON形式のデータで返却する事が出来ています。

usersテーブルのデータをJSON形式のデータで返却

respond_toメソッド
リンクをコピーしました

respond_toメソッドは、リクエストされたフォーマットによって処理を分ける事が出来るメソッドです。
下記の様に定義すると、リクエストされるフォーマットがjsonだった場合は、{render :json => オブジェクト}を返します。

respond_toメソッドでJSON形式のデータを返却する場合
1
2
3
4
respond_to |format|
  format.html
  format.json {render :json => オブジェクト}
end

また、リクエストされるフォーマットが指定されていない場合は、respond_toメソッドを記述したアクションのデフォルトのテンプレートが返ります。

フォーマットの指定は、urlの最後に.jsonとするとjson形式になって、.htmlとするとhtml形式になります。

アプリケーションで確認しよう
リンクをコピーしました

アプリケーションで挙動を確認します。

今回は、usersコントローラのindexアクションにrespond_toメソッドを記述するので、indexアクションのデフォルトのテンプレートは、app/views/users/index.html.erbです。

このテンプレートには、以下のように記述します。

app/views/users/index.html.erb | ユーザー情報をJSON形式のデータで返却する
1
2
3
4
<p>
【ニックネーム】<%= @users[:nickname] %><br>
【年齢】<%= @users[:age] %>
</p>

usersコントローラのindexアクションには、以下のようにリクエストされるフォーマットがjsonだった場合は、JSON形式のデータが返却される様に定義します。

app/controllers/users_controller.rb | ユーザー情報を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形式のデータが表示されます。
の方が良さそう。

リクエストするフォーマットをjsonにした結果

この様に、respond_toメソッドを使うことによって、リクエストされるフォーマットによって処理を分ける事が出来ます。

gem
リンクをコピーしました

これまでは、簡単なJSON形式のデータを返却する方法を解説してきましたが、より複雑なフォーマットで返す場合には、gemを利用します。

jbuilder
リンクをコピーしました

jbuilderは、 Railsにデフォルトで備わっているgemです。

jbuilderがデフォルトでRailsに備わっている様子

×××.json.jbuilderのファイルをviewディレクトリ配下に配置して、jbuilderのイディオムに従って記述すると、JSON形式のデータを簡単に構築する事が出来ます。

例えばindex.json.jbuilderに対して、下記の様に定義します。

app/views/users/index.json.jbuilder |
1
json.text "テキスト"

http://localhost:3000/users.jsonにアクセスすると、上記の記述がJSON形式のデータに展開されています。

JSON形式のデータに展開

今回は簡単なJSON形式のデータを構築しましたが、インスタンスを使ったより複雑なフォーマットもjbuilderで簡単に記述する事が出来ます。

詳しい使い方は、jbuilderの使い方辞典を参考にしてください。

ActiveModelSerializers
リンクをコピーしました

ActiveModelSerializersは、jbuilderよりもレスポンスが素早く直感的にコードを書く事が出来るgemです。

このgemを使うには、まずはGemfileに下記を追加してbundle installします。

Gemfile | gemを追加する
1
gem 'active_model_serializers', '~> 0.10.0'

次に、rails g serializer モデル名のコマンドを実行すると、app/serializers/モデル名_serializer.rbにファイルが生成されます。今回は、ユーザー情報をJSON形式のデータで返却したいのでモデル名にuserを指定します。

コンソール | userのシリアライザーを作成する
1
$ rails g serializer user

上記を実行すると、app/serializers/user_serializer.rbに下記のファイルが生成されます。このファイルのattributesには、JSON形式のデータで返したいプロパティを指定します。

シリアライザーの設定ファイル

例えば、下記のプロパティをJSONデータに含めたい場合は、

プロパティを確認

下記の様に、:nickname, :ageを追加します。

app/serializers/user_serializer.rb | attributesのプロパティを追加する
1
2
3
class UserSerializer < ActiveModel::Serializer
  attributes :id, :nickname, :age
end

そして、コントローラー(app/controllers/users_controller.rb) のindexアクションに対して、下記の様に記述します。

app/controllers/users_controller.rb | ActiveModel::Serializer::CollectionSerializerを使う
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)を渡します。

ActiveModel::Serializer::CollectionSerializer.newの第一引数と第二引数
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に渡します。

app/serializers/user_serializer.rb | attributesのプロパティを追加する
1
2
3
class UserSerializer < ActiveModel::Serializer
  attributes :id, :nickname, :age
end

http://localhost:3000/usersにアクセスすると、下記の様に各ユーザーのid, nickname, ageがJSON形式のデータで返却されます。

usersテーブルのレコードがJOSN形式のデータで返却されている

公式ドキュメント:ActiveModelSerializers

RailsでJSON形式のデータを受け取る方法
リンクをコピーしました

JSON形式のデータが送られてきた場合に、Railsでは自動的にparamsに格納されるのでparams["キー名"]でデータを取得する事が出来ます。

例えば、下記のJSON形式のデータをPOSThttp://localhost:3000/userspostmanで送信した場合は、

postmanでjsonデータを送信した場合

下記の様に、JSON形式の文字列で送信したデータがハッシュに自動変換されてparamsに格納されます。params["nickname"]で値を取得する事が出来ます。

コンソール | 送信されたデータの確認
1
2
3
4
5
[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を使います。

コンソール | JSON形式の文字列を取得したい場合
1
2
[1] pry(#<UsersController>)> request.body.read
=> "{\n\t\"id\": 1, \n\t\"nickname\"ぴよっち",\n\t\"age\": 22\n}"

また、このJSON形式の文字列は、JSON.parseを使ってキー名をシンボルのハッシュに変換する事も出来ます

コンソール | キー名をシンボルのハッシュに変換する
1
2
[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["キー名"]でデータを取得する事が出来ます。