この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Rack はとてもシンプルな規約に基づいたインタフェースです。
Ruby on Rails や Sinatraは、Rackの上に実装され、UnicornやPumaなどのWebサーバに渡されます。
今回は、Rackの基礎をさっと説明します。
■ せっかちなあなたへ
$ gem install rack
$ vi config.ru
run -> (env) { [200, {"Content-type" => "text/html"}, ["Hello, world"]]}
$ rackup config.ru
そして、 http://localhost:9292 にアクセスするだけ!
簡単に実装できました。
■ 改めて Rackとはなんぞや
http://rack.github.io にはこんな説明があります。
Rack provides a minimal interface between webservers that support Ruby and Ruby frameworks.
Web サーバと Rubyやフレームワークをつなぐ最小のインタフェースを提供している
rackの規約を満たしていれば、フレームワークやWebサーバを簡単に差し替えることができます。
rackには WEBrickというシンプルなWebサーバも搭載されており、rackの規約を満たすスクリプトを書くだけで簡単にWebアプリを作成することができます。
■ Rackの規約
最低限以下を満たしていればOK
- アプリとなるオブジェクトを記述して run に渡します。 (上記の例だと、runに渡している Procオブジェクト)
- オブジェクトは次の規約を満たすものとします
- 引数を1つもつcallメソッドが定義されている(慣習的に仮引数名は env)
- callメソッドは [ステータスコード, ヘッダのハッシュ, 本文の配列] を返す
通常は設定ファイルに記述します。慣習的に拡張子が.ruのファイルに記述します。
中身の実体は Rubyなので .rb でも良さそうですが、run などのDSLとして拡張されるので変更されているみたい。
Ruby on Rails のアプリひな形だと app_path/config.ru になります。
■ Rack Middleware
上記の規約を満たしていればOKなのですが、それだと 巨大な callメソッドになってしまいます。
Ruby が使えるのでクラスを切り出すことも可能ですが、そんな複雑なインタフェースをもつわけはありません。
use を使うことで、フィルタのように処理をつなげることができます。
たとえば、Basic認証を実装します。(このMiddlewareはRack標準に定義されています)
require 'rack/auth/basic'
use Rack::Auth::Basic, "input username" do |username, password|
username == "foo" && password == "secret"
end
run -> (env) { [200, {"Content-type" => "text/html"}, ["Hello, world"]]}
■ Rack Middleware の規約
次を満たせば Rack Middlewareとなります
- 最初の引数に アプリとなるオブジェクトを受け取る initializeメソッドが定義されている
- Rackの規約を満たす call メソッドが定義されている
use を使って複数呼び出すことができますが、順番に注意してください。
次の場合は MiddleA -> MiddleB -> MiddleC と呼ばれます。
use MiddleA
use MiddleB
use MiddleC
run App
■ Rails と Middleware
rack middleware コマンドで確認できます。
$ rack middleware
普段なかなか触らない Rackについて簡単に説明しました。
Railsのソースをながめると処理の流れをつかめるので、ぜひ追ってみてください。
抽象化しているので複雑ですが、実体は非常にシンプルです。