175
167

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Rails4] Grape で API を簡単に実装 & API を複数バージョンで分ける方法

Posted at

Grape を利用すると Restful な WEB-API が簡単に作成できるらしいので試してみました。その際、実際の運用を視野にいれて、次のこともやってみました。

  • 複数の API バージョン に対応する。
    • 例:http://ドメイン/api/v1/.. http://ドメイン/api/v2/..
  • 1つのソースがファットにならないよう モデル毎にソースを分ける

まずは Grape の導入手順から説明します。

Grape の導入手順

前提

  • 手元の OS:Mac OS X 10.9.5 (Mavericks)
  • Ruby:2.1.2
  • Rails:4.1.1

Grape は結果、0.9.0 が入りました。

手順

  • 適当な Rails プロジェクトを作成。

     $ bundle exec rails new grape_app --skip-bundle -T
    
  • Gemfile への追記。

    Gemfile
     #..
    
     gem 'grape'
    
     #..
    
  • gem をインストール。

     $ cd grape_app
     $ bundle install --path vendor/bundle
    

API の作成

前提

APIのソースコードは app/apis/ 下に置くこととします。ファイル構成はこんな感じ。

スクリーンショット 2014-10-09 17.47.13.png

ディレクトリ構成およびファイル名は、クラスの名前空間およびクラス名と一致させる必要があります。 大文字/小文字は、気にしなくてもいいみたい。

手順

  • 適当に Scaffold します。

     $ ./bin/rails g scaffold person name:string age:integer memo:text
     $ ./bin/rails g scaffold product name:string price:integer memo:text
     $ ./bin/rake db:migrate
    

    Person モデルと Product モデルが作られます。

  • app/apis/ 下の Ruby ファイルが読み込まれるようにします。

    config/application.rb
     #..
     
     module GrapeApp
       class Application < Rails::Application
         #..  
     
         config.paths.add File.join('app', 'apis'), glob: File.join('**', '*.rb')
         config.autoload_paths += Dir[Rails.root.join('app', 'apis', '*')]
       end
     end
    
  • 基底となるAPIクラスを作成します。

    • このファイルで各バージョンのAPIをマウントします(今回は、バージョン1のみ)。
    app/apis/api/root.rb
     module API
       class Root < Grape::API
         # http://localhost:3000/api/
         prefix 'api'
     
         mount API::Ver1::Root
         #mount API::Ver2::Root
       end
     end
    
  • バージョン1の中で、基底となるAPIクラスを作成します。

    • ここで 各APIの実体をマウントします。
    app/apis/api/ver1/root.rb
     module API
       module Ver1
         class Root < Grape::API
           # http://localhost:3000/api/v1/
           version 'v1'
           format :json
     
           mount API::Ver1::People
           mount API::Ver1::Products
         end
       end
     end
    
  • 各APIの実体を作成します。

    • 今回は「全件取得」と「1件取得」のAPIを作成します。
    app/apis/api/ver1/people.rb
     module API
       module Ver1
         class People < Grape::API
           resource :people do
     
             # GET /api/v1/people
             desc 'Return all people.'
             get do
               Person.all
             end
     
             # GET /api/v1/people/{:id}
             desc 'Return a person.'
             params do
               requires :id, type: Integer, desc: 'Person id.'
             end
             get ':id' do
               Person.find(params[:id])
             end
           end
         end
       end
     end
    
    app/apis/api/ver1/products.rb
     module API
       module Ver1
         class Products < Grape::API
           resource :products do
     
             # GET /api/v1/products
             desc 'Return all products.'
             get do
               Product.all
             end
     
             # GET /api/v1/products/{:id}
             desc 'Return a product.'
             params do
               requires :id, type: Integer, desc: 'Product id.'
             end
             get ':id' do
               Product.find(params[:id])
             end
           end
         end
       end
     end
    
  • 最後に、基底となるAPIクラスをルーティングに追加します。

    config/routes.rb
     Rails.application.routes.draw do
     #..
     
       mount API::Root => '/'
     
     #..
     end
    

動作確認

適当にデータを登録し、ブラウザでアクセスしてみます。

screen1 copy.png screen2 copy.png

screen3 copy.png screen4 copy.png

おわりに

簡単に API が作成できました。自身の課題として、次のものがあります。

  • Grape の GitHubページ に記載されている機能を検証できていない
  • エラーのハンドリングまわりの実装
  • JSONデータの入れ子に対応できるよう、テンプレートエンジンを導入(rabl が良い?)

今回はわりとよい感触を得られたので、引き続き触って評価してみようと思います。

175
167
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
175
167

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?