Rack ってなに?
Rack は Web サーバと Ruby プログラムや Ruby で書かれた Web アプリケーションフレームワークとの間に、最小限のインターフェースを提供します。
http://rack.rubyforge.org/Rack のインストール
gem install rack
Rack の簡単な始め方
Rack を使うには、まず call されるアプリケーションを書きます。call メソッドを定義し、引数に env を取ります。
# app.rb require 'rack' class TinyCaller def call(env) [200, {'Content-Type' => 'text/html'}, ["Hello, World."]] end end
続いて、Rack を使うための DSL ファイルとなる .ru ファイルを作成します。
# tiny_caller.ru require 'app' run TinyCaller.new
Rack を起動するには、コマンドラインから次のように入力します。-s オプションに webrick を指定すると WEBrick が Web サーバとして使用されます。
rackup -s mongrel -p 10080 tiny_caller.ru
Rack の基本的な使い方
Request クラス
Rack では、call されたときに引数として渡される env に環境変数一式がハッシュとして入っています。Request クラスはこの env をクラスのようにアクセスできるように補助してくれ、自然な形でのリクエストパラメタの利用が可能となります。
- Rack#GET は QUERY_STRING を parse したハッシュを返す
- Rack#POST は FORM からのパラメタを parse したハッシュを返す
- クエリパラメタについては、基本的には Request.new(env).params で取得可能。ハッシュとしてアクセスできる。(実は syntax sugar で、実装としては上記 GET と POST を利用している)
- Request#[](key)
- Request#[]=(key, value) は Request#params(key), Request#params=(key, value) へのショートカット
- Request#env で環境変数へハッシュのようにアクセス可能
- Request#cookies でクッキーへハッシュのようにアクセス可能
- Request#xhr? XMLHttpRequest として call されたなら true
- Request#url 呼び出した URL を String として返す
- Request#fullpath ルートからの相対パスをフルパスで返す
- Request#get?, Request#post?, Request#put?, Request#delete? HTTP Request のメソッドが何形式かを判定し、boolean を返す
Response クラス
Response は HTTP Response の構築をサポートするクラスです。なので、基本的には、
- HTTP status
- header
- body
Response#initialize(body=[], status=200, header={}, &block)
header には、自動的に "Content-Type" => "text/html" が追加されます。body は、文字列か文字列の集合を与えます。(厳密には to_str できれば何でもいいらしい)
Response#write と Response#finish
Response#finish を行うまで、 Response#write された内容が蓄積されます。body としたい内容を Response#write していき、最後に finish を呼び出し結果を確定させます。
その他
- [](key), []=(key, value) は header への syntax sugar
- Response#set_cookie(key, value)
- Response#delete_cookie(key, value={})
Response と Request を使った簡単なサンプル
# app.rb class TinyCaller def call(env) req = Rack::Request.new(env) res = Rack::Response.new res.write req.env.map {|k,v| "<li>#{k}: #{v}</li>"}.sort.join("\n") res.finish end end
Response をブロックで
# app.rb class TinyCaller def call(env) req = Rack::Request.new(env) Rack::Response.new.finish do |res| res.write "<h2>Rack Environment Variables</h2>" res.write req.env.map {|k,v| "<li>#{k}: #{v}</li>"}.sort.join("\n") end end end
Rack でセッションを使う
Rack でセッションを使うには、
- ru ファイルでセッションを使うことを宣言
- アプリケーションでは、Request#env['rack.session'] を通して利用(デフォルト)
Rack では、下記のように use を使って ru ファイルにミドルウェアを積んでいくことで簡単に機能強化ができるようになっています。
# tiny_caller.ru require 'app' use Rack::Session::Cookie run TinyCaller.new
# app.rb class TinyCaller def call(env) req = Rack::Request.new(env) session_data = req.env['rack.session'] session_data['counter'] ||= 0 session_data['counter'] += 1 Rack::Response.new.finish do |res| res.write "<li>count: #{session_data['counter']}</li>" end end end
細かい設定をしたい
ru ファイルで use する際にオプションを細かく指定することも可能です。
use Rack::Session::Cookie, :key => 'rack.session', :domain => 'foo.com', :path => '/', :expire_after => 2592000 All parameters are optional.via) http://rack.rubyforge.org/doc/classes/Rack/Session/Cookie.html
よりセキュアにしたい
今のところ、Rack の Session モジュールには Cookie しかありません。今後、サーバサイドで状態を管理するものがリリースされるのを期待するか、自分で作りましょう。(永続化は Rack のプロジェクトのスコープ外である可能性はあります。そこまでやってしまうと、Web フレームワーク化していくので。)
URI によってルーティングしたい
Rack::URLMap を使えば実現できます。ru ファイルでは、URLMap へのショートカットである map が提供されています。
# tiny_caller.ru require 'app' require 'another_app' map "/" do use Rack::Session::Cookie run TinyCaller.new end map "/app2" do run AnotherCaller.new end
HTML エスケープする
Rack::Utils#escape_html(string) を使います。
認証をしたい
Rack::Auth でできるんだろうけど、試していないので詳細不明。
もっと知りたい
当初、誤って「 CGI から Rails まで」としてましたが、Rails の Handler は TODO 扱いですね。現状は、対応していません。(Rails 自体の script/server で WEBrick と mongrel は簡単に切り替えられるので、あまりここは支障ないですが。)
Rack について調べながら、Rack のコードを読んでたんだけど、とても読みやすかった。全体の構造もわかりやすいし、各ファイルもコンパクトでざっと見ると内容が想像しやすい。
Rack の説明を読んでも使い方がよく分からない人は、(ぼくの説明が不十分or不適切か、)Web アプリに関する基本的なあれこれを理解したほうが早いと思うので Ruby のまじめな名著「Ruby アプリケーションプログラミング」を一度読んでみるのがおすすめ。Ruby で CGI アプリケーションを書くための解説の章で Web アプリケーションの基本的な仕組みについても丁寧に解説されていて、非常にわかりやすい。内容は少し古いけど、基本は変わらないので今でも十分使える。
オーム社 (2002/04)
売り上げランキング: 12952