Grapeを使ったAPI実装でのネストやパラメータ
移転しました →
Grapeをもう少し使ってみました。関連記事は↓
RailsのGrapeとJbuilderでAPI開発 - PILOG
基本形
# app/api/api.rb resource :items do get '/', jbuilder:'items' do @items = Item.all end end
パラメータを受け取る
全てのItemではなく、idに該当するItemだけが欲しいとき。
resource :items do get '/:id', jbuilder:'item' do @item = Item.find_by_id(params[:id]) end end
/api/items/1
というエンドポイントでid=1
のItemが得られます。
ネストする
- Item
- Entry
というモデルがあって、Item has many Entriesな関連を持っている場合はリソースをネストさせることが多いと思います。Railsのルーティングとかでもよくやるアレです。Grapeでも似たような書き方ができます。
resource :items do route_param :item_id do resource :entries do get '/', jbuilder:'entries' do @item = Item.find_by_id(params[:item_id]) @entries = @item.entries if @item end get '/:id', jbuilder:'entry' do @item = Item.find_by_id(params[:item_id]) @entry = @item.entries.find_by_id(params[:id]) if @item end end end end
上のコードにより2つのAPIが定義されます。
/api/items/1/entries
でItem(id=1)のEntryを全て返す/api/items/1/entries/1
でItem(id=1)のEntryのうち(id=1)のものを返す
ネストの階層はこのようになっています。
resource :items
route_param :item_id
resource :entries
2番めに出てくるroute_param
というのがありますが、実はこれresource
のエイリアスでGrapeの中では同じように扱われます。
公式ドキュメントによると元々はnamespace
というメソッドがあって、それに対するaliasとして以下のものが定義されているようです。
- namespace
- group
- resource
- resources
- segment
- route_param
読みやすくなるようコンテキストに応じて使えばよいということで、上のような場合はやはりresource(s)
やroute_param
が適切っぽいでしょう。
API定義全体
class API < Grape::API format :json formatter :json, Grape::Formatter::Jbuilder default_format :json resource :items do get '/', jbuilder:'items' do @items = Item.all end params do requires :id, type: Integer, desc: "Item ID" end get '/:id', jbuilder:'item' do @item = Item.find_by_id(params[:id]) end params do requires :item_id, type: Integer, desc: "Item ID" end route_param :item_id do resource :entries do get '/', jbuilder:'entries' do @item = Item.find_by_id(params[:item_id]) @entries = @item.entries if @item end params do requires :id, type: Integer, desc: "Entry ID" end get '/:id', jbuilder:'entry' do @item = Item.find_by_id(params[:item_id]) @entry = @item.entries.find_by_id(params[:id]) if @item end end end end end