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