[Rails x Angular] Part 1. Grapeを使ってRailsをApiサーバーとして使い、フロントをAngularに任せる方法

# はじめに

基本的にはRailsサーバーをApiサーバーとして扱って、フロントはAngularに任せたい。ネイティブアプリにも使いたいし。[これを参考に](http://blog.mah-lab.com/2014/11/24/angularjs-rails-code/)
あとから確認しますが、[AngularでもSEO対策できるしようですし。](https://prerender.io/)

とはいえ、結局まぁRailsでJSONを返すのもHTMLを返すのもルーティングやらコントローラーやらで切り分けするだけなので、融通を利かせられそうです。

# とりあえずGrapeでサーバーサイドを作る

簡単にできます。Grape。

とりあえす、プロジェクトを作ります。
rails new hoge --database=hoge --skip-bundle とかします。

```rb:Gemfile
source 'https://rubygems.org'↲

ruby '2.1.5'↲

# rails
gem 'rails', '4.1.8'
gem 'grape'

# db
gem 'sqlite', group: :development
gem 'pg', group: :production
gem 'rails_12factor', group: :production

gem 'uglifier', '>= 1.3.0'
gem 'jbuilder', '~> 2.0'
gem 'enumerize'
gem 'inherited_resources'
gem 'has_scope'

# login
gem 'devise'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.3'
gem 'bootstrap-sass'
gem 'font-awesome-rails'
gem 'compass-rails'

# javascripts↲
gem 'bower-rails', '~> 0.9.1'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'


group :development do
  gem 'spring'
  gem 'quiet_assets'
  gem 'brakeman', group: :development
  gem 'rails_best_practices', group: :development
  # nice show of sql result
  gem 'hirb'
  gem 'hirb-unicode'
  # check unuseful sql
  gem 'bullet'
  # good to read error screen
  gem 'better_errors'
  gem 'binding_of_caller'
  # Pry
  gem 'pry-rails'
  gem 'pry-coolline'
  gem 'pry-byebug'
  gem 'pry-doc'
  gem 'awesome_print' # remove to get mongo error away
  # easy print-debug↲
  gem 'tapp'
end

# Use unicorn as the app server
gem 'unicorn'
```

とりあえずbundle install

rake db:createなりrake db:migrateなりしておきます。

# Routing

```rb:config/routes.rb
Rails.application.routes.draw do↲
↲
  mount Api => '/'↲
  mount LoveloveApi => '/lovelove'
  mount DamedameApi => '/damedame'
・
・
・

end
```

↑の名称に意味はありません。

↑で指定したApiとかLoveloveApiとかにコードを書いていきます。
いくつでもmountできて、prefixといっていいのか、ルーティングの上位の部分を指定できます。


# config/application.rb

以下を追記

```rb
# api
    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
```

# Apiの中身を書く

↑のルーティングに沿うと以下の構成になります。

+ ~/PROJECT_NAME/app/api/api.rb
+ ~/PROJECT_NAME/app/api/lovelove_api.rb
+ ~/PROJECT_NAME/app/api/damedame_api.rb

apiディレクトリはmkdirして下さい。

```rb:api.rb
  class Api < Grape::API↲
    version 'v1', using: :path # set version
    format :json # set format
    prefix :api # set prefix

    helpers do
      def current_user
        @current_user ||= User.authorize!(env)
      end

      def authenticate!
        error!('401 Unauthorized', 401) unless current_user
      end
    end

    # test
    resource :test do
      desc 'this is a test'
      get :say do
        {dameyo: damedame, a: 1, b: 2}
      end
    end


    resource :statuses do↲
      desc "Return a public timeline."↲
      get :public_timeline do↲
        Status.limit(20)↲
      end↲
・
・
・
```

こんな感じで書いていきます。
サンプルは[GithubのReadme.md](https://github.com/intridea/grape)にあります。

# ApiのURL

今回の場合、
- http://PROJECT_URL/api/v1/test/say
- http://PROJECT_URL/lovelove/api/v1/test/say
- http://PROJECT_URL/damedame/api/v1/test/say

な感じになります。

# で、叩いてみた結果

これを叩いてみます。
http://PROJECT_URL/api/v1/test/say

ブラウザでURLを入力してブラウザに表示させてみました。

```json:
{dameyo: damedame, a: 1, b: 2}
```

こんな感じです。

想像以上に超簡単でした。。。

# そしてAngular...

[つづく...](http://qiita.com/tsumekoara/items/0c1cffd183f4c50f603c)
http://qiita.com/tsumekoara/items/0c1cffd183f4c50f603c

# references

- [GithubのReadme.md](https://github.com/intridea/grape)
- [良いサンプルになります](http://dev.classmethod.jp/server-side/ruby-on-rails/ruby-on-rails_create_grape_web-api/)
- [なんかわかりやすかったです](http://monmon.hatenablog.com/entry/2014/11/22/202913)
- [最終的にはこんな感じにもっていきたいです](http://blog.mah-lab.com/2014/11/24/angularjs-rails-code/)
- http://qiita.com/anoworl/items/756f01cc3d188ebad139
- http://qiita.com/zaru/items/fa64a4e00b76ea6ce36f
- http://qiita.com/hkusu/items/2ca0323cc276ab31e926
- http://qiita.com/kidachi_/items/5793bcb307fa52026b6a
- http://morizyun.github.io/blog/rails-grepe-api-heroku-ruby/
- https://prerender.io/