active_model_serializersからjsonapi_resourcesに乗り換えた

背景

趣味プロジェクトでモデルのシリアライズactive_model_serializers を使っていたが、なんだかissueとか見てると開発に暗雲が立ち込めているぞ???最近rails_apiのデフォルトかなんかになったかで盛り上がっていたはずなのにどうした。 ブレイキンなチェンジも多いし、JSON APIの仕様を満たせていない部分があってember-dataのうまみが生かせないので変えることにした。JSON APIの公式ページからImplementationsを探すと jsonapi_resources というスター数の多いイケてそうなgemを見つけたので使ってみることにした。

所感

READMEが懇切丁寧に書いていて間違いなくいいgemだなーと思った。すごくカスタマイザブルに作ってあるし、さくさくAPIが作れる。最高。 クエリパラメタによるfilterとかsort機能がデフォルトで付いていて素晴らしい。

ember-dataと組み合わせれば3分でSPAが作れちゃいそう。

簡単な処理の流れ

JSONAPI::Resourceクラスメソッドrecords , apply_filter, find もしくは find_by_key という順番でリソースが絞り込まれていく。最終的に見つかったリソースをJSON API準拠のフォーマットにする。

self.records

検索されるデータのおおもとでデフォルトでは Class.all になる。 以下の用に current_user がもつものだけ出すとかここで制約かけちゃうことができる。

class PostResource < JSONAPI::Resource
  def self.records(...)
    current_user.posts
  end
end

self.apply_filter

Resourceクラスは filters メソッドを提供していて、ここで宣言すると完全一致でフィルタリングできるようになる。

my-resources?filter[my-property]=hoge

完全一致以外がいいとき、たとえば date が範囲内にあるかいう場合は self,apply_filter をオーバーライドする。

class PostResouce < JSONAPI::Resources
  filter :date

  self apply_filter(filter, value ...)
     case filter
     when date
       records.date(value)
     else
       super
     end
  end
end

self.find, self.find_by_key

前者はindex、後者はshowに使われる。オーバーライドでさらに細かな調整ができるのが一点注意がある。

superで得られるデータの型がArrayなのでscopeとか使えない。

ページネーター

jsonapi_resouces はデフォルトでページネーションをサポートします。ページネーターというものをリソースに適用して利用します。実装済みページネーターには pagedoffset の二種類があります。

paged

いわゆる普通のページネーションの形。10ページ区切りのうち、何ページ目。

パラメータはnumberとsize。 numberは指定されなければ1ページ目が出力される。 sizeが指定されなければdefault_page_sizeが使われる。

params => page[number], page[size]

offset

いくつ目のデータから、何個のデータを表示するか指定するページネータ。

○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○
        |---------------->|
      offset         limit(how many)

5番目のデータから10個のデータを取得

params => page[offset], page[limit]