RailsでAPIを作るならGrapeを使うってのが定番っぽいので使ってみました。
参考にしたのはこのへん
Grapeの導入〜Hello World
インストールはgem install
すればOKです。次にAPIの実装コードを書くファイルを用意します。僕は#{Rails.root}/app/api/api.rb
としました。
# app/api/api.rb
class API < Grape::API
format :json
resource :items do
get '/hello' do
{hello: "world"}
end
end
end
そしてroutes.rb
にてGrapeをマウントします。
# routes.rb
mount API => "/api"
APIは↑で定義したクラス名です。
以上のコードでhttp://domain.com/api/items/hello
というURLに対するGETで{hello:"world"}
というレスポンスが得られます。これが概要。
mountとプレフィックス
mount API => "/api"
としましたがこれは自由に変更できます。mount API => "/"
と、ルートを指定できます。
この他にAPIクラスにprefixを付けることができるようになっていて、
class API < Grape::API
format :json
prefix "api" #この行
# ...
end
↑のように書くとAPIクラスに定義されているAPIのURLにapi
と付けられるようになります。
ところで、マウントパスとprefixの両方定義できます。Grapeの使い始めで色々いじっていたときに両方に"api"
という値を入れてしまい、/api/api/items/hello
というURLでアクセスしなければならないことに気が付かず、/api/items/hello
が404になってしまうことにしばらくハマりました。
JbuilderでViewを書く
さきほどのサンプルではレスポンスのjsonを直書きしましたが、プロダクションレベルではさすがにそんなことはしません。htmlのViewを作るときのように別ファイルを使って書きます。
Rails4にはjsonを作るためのjbuilderというgemがデフォルトで含まれるのでそれを使うと良いでしょう。他にはRablというものがあります。
GrapeでJbuilderを使うにはgrape-jbuilder
というgemを導入します。
導入はGemfile
にgem 'grape-jbuilder
でおk。
すると、Grape::Formatter::Jbuilderが使えるようになります。FormatterはAPIクラスで次のように指定できます。
class API < Grape::API
format :json
formatter :json, Grape::Formatter::Jbuilder
end
あとはjbuilderを使うAPIにどのViewを対応させるかを書いてあげれば使えるようになります。
app/views/api/items.jbuilder
ファイルを使う場合、apiのほうにはjbuilder:'items'
と書きます。
# app/api/api.rb
resource :items do
get '/', jbuilder:'items' do
@items = Item.all
end
end
Viewのほうには、@items
を使うようなコードを書くと動的にViewを生成できるようになるわけです。シンタックスは違えど、ERBと同じような感じです。
# app/views/api/items.jbuilder
json.items do
json.array!(@items) do |item|
json.(item, :id, :title, ..などなど..)
end
end
例えばこのようなjsonが得られるわけですね。
{
"items": [
{
"title": "hogehoge",
"id": 1
},
{
"title": "foobar",
"id": 2
}
]
}