Rails
api
ActiveModelSerializer

Railsのactive_model_serialiserについて学ぶ_100DaysOfCodeチャレンジ10日目(Day_10:#100DaysOfCode)

はじめに

この記事はTwitterで人気のハッシュタグ#100DaysOfCodeをつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した10日目の記録です。

動作環境

  • ruby 2.4.1
  • Rails 5.0.1

現在学習している内容のリポジトリ

https://github.com/yuta-ushijima/notebook-api-on-rails

本日学んだこと

  • active_model_serialiser(アクティブ・モデル・シリアライザー)

active_model_serialiser(アクティブ・モデル・シリアライザー)とは?

RailsをAPIサーバーとして使う際に事実上必須となるライブラリ。JSONを作成する際に色々と便利な機能を提供してくれる。

カスタマイズ性が高いので使いこなせればかなり心強い味方に。

公式リポジトリ

https://github.com/rails-api/active_model_serializers/tree/0-10-stable

実行コマンド

bundle exec rails g serializer モデル名

(例)
bundle exec rails g serializer contact

# 実行結果
Running via Spring preloader in process 3267
create  app/serializers/contact_serializer.rb

上記のコマンドを実行することで、appディレクトリ配下にserializersディレクトリが自動で作成され、指定したモデル名のファイル(ここではcontact_serializer.rb)が作成される。

なお、serializer生成時のデフォルトは以下のような中身になっています。

class ContactSerializer < ActiveModel::Serializer
  attributes :id
end

ファイルの中身について

ここでもう一度デフォルトのファイルを表示します。

class ContactSerializer < ActiveModel::Serializer
  attributes :id
end

ファイルに記述されているattributesですが、このメソッドにシンボルを渡すと、render jsonなどでJSONオブジェクトを表示させた際にレスポンスされるkeyとvalueを絞り込むことができます。

現在の状態でGETにより一覧取得のAPIを叩くと、idとその値だけがレスポンスとして返ってきます。

# localhost:3000/contactsをGETで叩く
# 以下は実行結果

[
    {
        "id": 1
    },
    {
        "id": 2
    },
    {
        "id": 3
    },
    {
        "id": 4
]

レスポンスされるJSONのアダプタを設定

ActiveModelSerializerには、アダプター(JSONの表示形式)を3種類用意しています。

  • :attributes (default)
  • :json
  • :json_api

先ほど紹介したattributesはデフォルトで設定されているアダプタです。

残りの:json:json_apiをデフォルトで使いたい場合には、initializersディレクトリに別途ams.rbというファイルを作成し、そこに以下のようなコードを書く必要があります。

# config/initializers/ams.rb
ActiveModel::Serializer.config.adapter = :json_api

こうすることで、JSONAPIという、JSONの仕様を決めている組織が制定している表示形式に沿ったレスポンスが返ってきます。

2018年6月現在、最新の仕様バージョンはv1.0。

アダプタをjson_apiにした時と、デフォルトのattributesにした時の違いは以下の通り。

attributes

[
    {
        "id": 1,
        "name": "中島 光",
        "email": "rhianna_walsh@maggio.net",
        "birthdate": "2016-05-02",
        "birthday": "2016/05/02"
    }
  ]
}

json_api


{
    "data": [
        {
            "id": "1",
            "type": "contacts",
            "attributes": {
                "name": "中島 光",
                "email": "rhianna_walsh@maggio.net",
                "birthdate": "2016-05-02",
                "birthday": "2016/05/02"
            }
        }
   ]
}

:json_api形式だと、より構造が明示的になっているのがわかります。

typeの値として書かれているのがモデル名で、attributesに記載されているのが、initializerのファイルでattributesメソッドに渡したシンボルがkeyとvalueでそれぞれレスポンスとして返ってきていますね。

参考リンク

https://qiita.com/romukey/items/b78906e91a0355e1e77a

https://techracho.bpsinc.jp/hachi8833/2017_09_28/45536

https://sandragon.hatenablog.com/entry/2018/02/03/180018