Grapeを使ってRESTfulAPIを簡単作成 その1 Grape

## 概要
Grapeを使うと、rails、sinatraなどのRackアプリケーションで、RESTfulAPIを簡単に構築できます。
[GitHub: ruby-grape/grape](https://github.com/ruby-grape/grape)

このページでは、railsアプリケーションが用意されていることを前提としています。

## 目次
**1.Grapeを使ってRESTfulAPIを簡単作成 その1 Grape**
2.[Grapeを使ってRESTfulAPIを簡単作成 その2 Grape::Entity](http://qiita.com/Esfahan/items/bdae2545e41588ccd1a5)
3.[Grapeを使ってRESTfulAPIを簡単作成 その3 Grape::Swagger](http://qiita.com/Esfahan/items/35001482d3c39e27fbab)

## 環境
- rails 5.0.0.1
- ruby 2.3.1

## まずはgemをインストール
下記を追記

```rb:Gemfile
# api
gem 'grape'
```

bundle install

```bash
$ bundle install --path vendor/bundle
```

## DBtableの構成
### usersテーブルを作成

modelを生成する

```
$ bundle exec rails g model User name:string email:string age:integer
```

Table: users
Model: User

| col | type |
| :-- | :-- |
| name | string |
| email | string |
| age | integer |

### seeds
サンプル用にデータを用意します。
db/seeds.rbを下記の内容で作成します。

```rb:db/seeds.rb
User.create(name: 'Sony', email: 'sony@sample.com', age: '40')
User.create(name: 'Fredo', email: 'fred@sample.com', age: '38')
User.create(name: 'Tom', email: 'tom@sample.com', age: '35')
User.create(name: 'Michael', email: 'michael@sample.com', age: '33')
User.create(name: 'Connie', email: 'connie@sample.com', age: '30')
```

DBにinsert

```
$ bundle exec rake db:seed
```

## ディレクトリ構成
下記のディレクトリ構成にします。

```
~/sample_api/
　　├ app/api/
　　│　　　　└ api.rb
　　│　　　　└ resources/
　　│           └ v1/
　　│　　　　　　　  └ root.rb
　　│　　　　　　　  └ users.rb
```

- app/api/api.rb
- app/api/resources/v1/root.rb  
この2つのファイル名は好きなもので構いません。
その場合は、後述のマウントの定義部分のファイル名も適宜変更してください。

## autoloadの設定

app/apiの下のファイルがautoloadされるようにします。

```rb:config/application.rb
module SampleApi
  class Application < Rails::Application
    #..  
    # app/api以下のrbファイルをautoload
+   config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
+   config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
  end
end
```

## APIの作成
下記の図のような[親-子-孫-ひ孫]の関係でマウントさせます。

```
config/routes.rb  # [親]ルーティングの設定
  └ app/api/api.rb # [子]API親クラス
      └ app/api/resources/v1/root.rb # [孫]API v1の親クラス
          └ app/api/resources/v1/users.rb # [ひ孫]userAPIのクラス
```

**[親] config/routes.rb**
ルーティングの設定をします。

```rb:config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

+ # app/api/api.rbをマウント
+ mount API => '/'
end
```

**[子] app/api/api.rb**
API親クラスを作成します。

```rb:app/api/api.rb
class API < Grape::API
  # urlの第１セグメント名 ex) http://localhost/api/
  prefix 'api'
  # app/api/resources/v1/root.rbをマウント
  mount Resources::V1::Root
end
```

**[孫] app/api/resources/v1/root.rb**
API v1の親クラスを作成します。

```rb:app/api/resources/v1/root.rb
module Resources
  module V1
    class Root < Grape::API
      version 'v1'
      format :json
      content_type :json, 'application/json'

      # app/api/resources/v1/users.rbをマウント
      mount Resources::V1::Users
    end
  end
end
```

**[ひ孫] app/api/resources/v1/users.rb**
userAPIのクラスを作成します。
下記の2種類のAPIを作成します。

- user情報を全て取得する
 - http://localhost:3000/api/v1/users
- 指定したidのuser情報を1件取得する
 - http://localhost:3000/api/v1/users/{:id}

```rb:app/api/resources/v1/users.rb
module Resources
  module V1
    class Users < Grape::API
      resource :users do
        # http://localhost:3000/api/v1/users
        desc 'user list'
        get do
          present User.all
        end

        # http://localhost:3000/api/v1/users/{:id}
        desc 'user'
        # パラメータ設定
        params do
          # 必須項目
          requires :id, type: Integer, desc: 'user id'
        end
        get ':id' do
          present User.find(params[:id])
        end
      end
    end
  end
end
```

## 表示確認
webrick起動
下記のように表示されれば成功です。

```
$ bundle exec rails s -b 0.0.0.0
```

user情報を全て取得するAPI
http://localhost:3000/api/v1/users

```
[

    {
        "id": 1,
        "name": "Sony",
        "email": "sony@sample.com",
        "age": 40,
        "created_at": "2016-12-07T02:31:46.000Z",
        "updated_at": "2016-12-07T02:31:46.000Z"
    },
    {
        "id": 2,
        "name": "Fredo",
        "email": "fred@sample.com",
        "age": 38,
        "created_at": "2016-12-07T02:31:46.000Z",
        "updated_at": "2016-12-07T02:31:46.000Z"
    },
    {
        "id": 3,
        "name": "Tom",
        "email": "tom@sample.com",
        "age": 35,
        "created_at": "2016-12-07T02:31:46.000Z",
        "updated_at": "2016-12-07T02:31:46.000Z"
    },
    {
        "id": 4,
        "name": "Michael",
        "email": "michael@sample.com",
        "age": 33,
        "created_at": "2016-12-07T02:31:46.000Z",
        "updated_at": "2016-12-07T02:31:46.000Z"
    },
    {
        "id": 5,
        "name": "Connie",
        "email": "connie@sample.com",
        "age": 30,
        "created_at": "2016-12-07T02:31:46.000Z",
        "updated_at": "2016-12-07T02:31:46.000Z"
    }

]
```

指定したidのuser情報を1件取得するAPI
http://localhost:3000/api/v1/users/4

```
{

    "id": 4,
    "name": "Michael",
    "email": "michael@sample.com",
    "age": 33,
    "created_at": "2016-12-07T02:31:46.000Z",
    "updated_at": "2016-12-07T02:31:46.000Z"

}
```

次項： [Grapeを使ってRESTfulAPIを簡単作成 その2 Grape::Entity](http://qiita.com/Esfahan/items/bdae2545e41588ccd1a5)

## 参考
[[Rails4] Grape で API を簡単に実装 ＆ API を複数バージョンで分ける方法](http://qiita.com/hkusu/items/2ca0323cc276ab31e926)