Edited at

RailsのAMSとforemanについて学ぶ_100DaysOfCodeチャレンジ15日目(Day_15:#100DaysOfCode)

More than 1 year has passed since last update.


はじめに

この記事はTwitterで人気のハッシュタグ#100DaysOfCodeをつけて、

100日間プログラミング学習を続けるチャレンジに挑戦した15日目の記録です。


動作環境


  • ruby 2.4.1

  • Rails 5.0.1


現在学習している内容のリポジトリ

https://github.com/yuta-ushijima/notebook-api-on-rails


本日学んだこと


  • Foremanについて

  • リクエストを受け付けるJSONのフォーマットを指定するメソッドの実装


Foremanとは?

rails servernpm run devのような実行するコマンドが複数ある時に、このgemを入れることで

foreman startコマンド一発で同時に実行できる便利なgem。


公式リポジトリ

https://github.com/ddollar/foreman


製作者のページ

http://blog.daviddollar.org/2011/05/06/introducing-foreman.html

# Gemfile

gem 'foreman'

railsのルートディレクトリにforemanを起動させるために必要なファイルであるProcfileを作成しましょう。

作成したProcfileに、webサーバーを起動するコマンドを追記します。

# Procfile

web: PORT=3000 bundle exec rails s

この内容の意味としては、「webサーバーとして、rails serverを使ってね。ポート番号は3000を使うように。」といったところですね。

Foremanではデフォルトのポートが5000になっているので、そのほかのポートを指定したい場合は別途指定が必要なのです。

あとは、foremanコマンドを使うために、システムにもforemanのgemをインストールしましょう。

gem install foreman


TIPS

bundle exec foreman startのように実行すると、先に記述したポート指定箇所で以下のようなエラーが発生します。

Yutas-MacBook-Air:notebook-api-on-rails ushijimayuuta$ bundle exec foreman start

11:21:42 web.1 | started with pid 7745
11:21:42 web.1 | /Users/ushijimayuuta/workspace/Rails/notebook-api-on-rails/vender/bundle/ruby/2.4.0/gems/foreman-0.64.0/bin/foreman-runner: line 41: exec: PORT=3000: not found
11:21:42 web.1 | exited with code 127
11:21:42 system | sending SIGTERM to all processes

「bundle execで実行したけど、PORT=3000なんてものはないよ」と怒られているわけですね。

これを解消するために、-pオプションを使ってProcfileを以下のように書き換えます。

# Procfile

web: bundle exec rails s -p 3000

これでエラーが出ずにforemanを実行することができました。

(「だったら、最初から上記の記述でいいんじゃね?」というツッコミは、なしでお願いします...笑)

ちなみに、gemがシステムのどこにインストールされたか知りたい時は、以下のコマンドを使うと確認できます。

gem environment

上記のコマンドを実行すると、以下のような情報が返ってきます。GEM PATHという項目がありますので、そこが該当箇所ですね。

RubyGems Environment:

- RUBYGEMS VERSION: 2.6.11
- RUBY VERSION: 2.4.1 (2017-03-22 patchlevel 111) [x86_64-darwin17]
- INSTALLATION DIRECTORY: /Users/ushijimayuuta/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0
- USER INSTALLATION DIRECTORY: /Users/ushijimayuuta/.gem/ruby/2.4.0
- RUBY EXECUTABLE: /Users/ushijimayuuta/.rbenv/versions/2.4.1/bin/ruby
- EXECUTABLE DIRECTORY: /Users/ushijimayuuta/.rbenv/versions/2.4.1/bin
- SPEC CACHE DIRECTORY: /Users/ushijimayuuta/.gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /Users/ushijimayuuta/.rbenv/versions/2.4.1/etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-darwin-17
- GEM PATHS:
- /Users/ushijimayuuta/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0
- /Users/ushijimayuuta/.gem/ruby/2.4.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /Users/ushijimayuuta/.rbenv/versions/2.4.1/bin
- /usr/local/Cellar/rbenv/1.1.1/libexec
- /Users/ushijimayuuta/.rbenv/shims
- /Users/ushijimayuuta/.rbenv/bin
- /usr/local/bin
- /usr/bin
- /bin
- /usr/sbin
- /sbin
- /sbin


リクエストを受け付けるJSONのフォーマットを指定するメソッドの実装

APIを作成する時に、どのようなリクエストなら受け付けるかを指定できると、よりセキュリティを高めることができます。

今回はapplication_controller.rbに受け付けるJSONのフォーマットを制御するensure_json_requestメソッドをの学習しました。

# application_controller.rb

class ApplicationController < ActionController::API
before_action :ensure_json_request

def ensure_json_request
return if request.headers["Accept"] =~ /vnd\.api\+json/
render :head, status: 406
end
end

メソッドの中身を説明しておきましょう。

before_actionにより、APIの各アクションが実行される前に、まずこのensure_json_requestが実行されるようになります。

中身の説明としては、まずensure_json_requestが呼ばれると、1行目による条件分岐が走りますね。

request.headerにより、リクエストヘッダーの"Accept"を取得し、=~で正規表現を使って右辺である/vnd\.api\+json/と比較。

それがtrueであればreturnされます。

そうじゃない場合は、ステータスコードの406(Not acceptable)を返すという処理ですね。

これによってAcceptにapplication/vnd.api+json、つまりJSONのフォーマットの一つであるJSON API以外が指定された場合は、リクエストを受け付けなくなります。

 ## まとめ

Active_Model_SerializerでMediaTypeを使うことで、リクエストのレスポンス形式を指定できるということですね。


参考リンク

https://wa3.i-3-i.info/word15786.html