It’s now or never

IT系の技術ブログです。気になったこと、勉強したことを備忘録的にまとめて行きます。

【Rails4】GrapeをつかってAPIを作成する

Grapeとは

REST-likeなAPIを作成する為のフレームワークです。 詳しくは、Grape githubを参照してください。

今回は、サンプルアプリケーションを作成し、jsonを返すAPIを動かしてみます。

サンプルプロジェクトにGrapeをインストール

任意のRailsアプリケーションを作成します。

rails new grape_api --skip-bundle -T

Gemのインストール

作成したアプリケーションのGemfileを編集し、grapeのGemをインストールします。

■ Gemfile

gem 'grape'
bundle install
// ※ローカルにインストールする場合は、--path vendor/bundleをつける

ディレクトリを作成する

API経由でデータを参照するために任意のモデルを作成します。

# userテーブルを作成しDBへ反映
rails g scaffold user name:string
rake db:migrate

ディレクトリは、下記のような構成にします。

- app
  - apis
    - api
      -v1
       - users
      -vXX
# とりあえず、v1のディレクトリのみ作成
mkdir -p app/apis/api/v1

今回は、上記のファイル構成を元に、

  • http://[ホスト]/api/v1/users
  • http://[ホスト]/api/v1/users/[user_id]

という2つのAPIを作成します。

ファイルの自動インポートの設定を行なう

apisディレクトリ配下に置かれたファイルが自動的にRailsのファイルパスに追加されるようにapplication.rbを以下のように編集します。

■ config/application.rb

module GrapeApi
  class Application < Rails::Application
    # app/api配下の.rbファイルを読み込み対象にする
    config.paths.add File.join('app', 'apis'), glob: File.join('**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'apis', '*')]
  end
end

APIのパスをルーティングする

APIのルートパスを定義します。

■ config/routes.rb

Rails.application.routes.draw do
・・・
  # APIモジュールのBaseクラスを'/'Pathとして定義する
  mount API::Base => '/'
・・・
end

Baseクラスを作成

ルーティングしたAPI::Baseクラスを定義します。
prefixにapiを定義することでhttp://[host]/apiのpathを構成することができます。

■ /app/apis/api/base.rb

module API
  class Base < Grape::API
    # Baseクラスのpathを定義する
    prefix 'api'

  end
end

上記のBaseクラスと同じようにv1ディレクトリ配下にもbase.rbを作成します。
versionを定義することでhttp://[host]/api/v1のpathを構成することができます。
formatAPIのレスポンスデータのフォーマットをjsonに指定しています。

■ /app/apis/api/v1/base.rb

module API
  module V1
    class Base < Grape::API
      version 'v1'
      format :json
    end
  end
end

先ほど作成したAPI::BaseAPI::V1::Baseをマウントします。

■ /app/apis/api/base.rb

module API
  class Base < Grape::API
    # Baseクラスのpathを定義する
    prefix 'api'

    # v1のBaseクラスをマウントする
    mount API::V1::Base
  end
end

apiクラスを作成

v1ディレクトリ配下にusersクラスを作成します。

resourceapiのpathを定義しています。

■ /app/apis/api/v1/users.rb

module API
  module V1
    class Users < Grape::API
      # `users`resource配下にすることで
      # /api/v1/usersのapiとしてアクセスできる
      resource :users do
        # GET http://[host]/api/v1/users
        get do
          User.all
        end

        # パラメタバリデーション
        params do
          requires :id, {type: Integer, desc: 'user id.'}
         end
         # GET http://[host]/api/v1/users/[user_id]
         get ':id' do
          User.find(params[:id])
         end
      end
    end
  end
end

API::V1::UsersAPI::V1::Baseにマウントします。

■ /app/apis/api/v1/base.rb

module API
  module V1
    class Base < Grape::API
      version 'v1'
      format :json
    end
    mount API::V1::Users
  end
end

サンプルデータを作成してAPIにアクセス

ローカル環境でRailsサーバを起動します。

rails server

http://localhost:3000/usersにアクセスして、画面上から適当にデータを作成します。

f:id:inon29:20150907082655p:plain

  • http://localhost:3000/api/v1/usersにアクセスするとUsersテーブルのデータの全件が取得できます。

f:id:inon29:20150907082705p:plain

  • http://localhost:3000/api/v1/users/1にアクセスするとUsersテーブルのデータの1件目が取得できます。

f:id:inon29:20150907082714p:plain

参考サイト

http://kzy52.com/entry/2014/11/07/084023 http://qiita.com/hkusu/items/2ca0323cc276ab31e926