http://article.yeeyan.org/view/52654/18184
Rack提供了Web伺服器和Ruby開發架構之間的介面。它將架構編寫者從為每個Web伺服器單獨編寫一個處理模組的繁重負擔中解脫出來,可以節省大量重複勞動。
Ruby社區幾乎每個星期都會有新的架構出現,但是這些架構裡面,Rack 並沒有得到足夠的關注。它應該被關注。同時,為了全面利用Rack, 在下一個 Rails 穩定版本2.2 之後會有一個更好的公用介面。
Rack 最初的靈感來自於Python的 wsgi ,並且由於它的簡單性和準確性,很快在Ruby社區成為了一個實際的web應用/伺服器介面。你可能想看看來自於Rack之父-Christian Neukirchen 的Rack介紹。
Rack是什麼 ?
- Rack API Docs
實際上,你可以把"Rack"分成兩部分:
Rack 規則
Rack規則指定一個Rack應用和webserver應該如何精確的互動:
- Rack Specification
這隻是個簡要的說明,你可以在這裡看到更詳細的內容。
嚴格的講,為了寫一個Rack ready application你不需要這個rack gem。這樣做僅僅是為了規範:
Rack Gem
Rack gem 是一個公用類和輔助類的集合,它可以使每一個Rack app開發人員更輕鬆。它包括了基本的request, response, cookies 以及sessions的實現. 還有相當多有用的中介軟體。總之,安裝rack gem,你只需要這樣:
$ sudo gem install rack
總結
- Rack 是一個支援你自己Ruby架構的架構.
- Rack 提供一個不同web伺服器和你的架構/應用之間的介面。使它可以更容易的讓你的架構/應用對任意支援Rack的web伺服器相容– Phusion Passenger, Litespeed, Mongrel, Thin, Ebb, Webrick 僅舉幾例.
- Rack消減你的成本.你可以免費的得到request, response, cookies, params 以及sessions .
- 沒有類衝突使得在用一應用使用多個架構成為可能。 Rails 和 sinatra 整合 是個很好的例子。
- 中介軟體 ! 想一想Rails的 before_filter/after_filter 可以在支援Rack的不同架構重複使用。例如,在你的Rails應用,Sinatra應用和你自定製的Rack應用裡都可以使用同一個Anti-spamming rack中介軟體。
例子
讓我們使用mongrel,從一個可能是最小的rack應用例子來開始。
1 2 3 4 5 6 7 8 9 10
|
require 'rubygems' require 'rack'
class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, "Hello Rack!"] end end
Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292 |
上面的代碼傳一個HelloWorld對象到mongrel的rack處理器,指定了9292連接埠。
The HelloWorld object遵循了rack規範 :
- call方法僅帶一個env參數
- call() 方法返回一個數組,包含這三個值 [http_status_code, response_headers_hash, body]
這就夠了! 運行指令碼,然後瀏覽器裡輸入http://localhost:9292, 你就會看到這個耀眼的 “Hello Rack!” 資訊。
等等,既然是一個響應call()的ruby過程,為什麼不用一個proc來代替呢? 那麼,沒有理由不這麼做:
1 2 3 4
|
require 'rubygems require 'rack'
Rack::Handler::Mongrel.run proc {|env| [200, {"Content-Type" => "text/html"}, "Hello Rack!"]}, :Port => 9292 |
另一種常見的模式是用method(:something), 這會返回一個 Method class 對象:
1 2 3 4 5 6 7 8
|
require 'rubygems' require 'rack'
def application(env) [200, {"Content-Type" => "text/html"}, "Hello Rack!"] end
Rack::Handler::Mongrel.run method(:application), :Port => 9292 |
帶走你巨慢的“Hello World”表演吧,你不可能再寫個比這更快的"Hello World" ruby 應用了。
Rack it up’
如我之前所說,rack gem為rack app開發人員帶來一大堆有用的東西。 rackup 就是其中之一.在前一個例子裡,我直接用了mongrel處理器Rack::Handler::Mongrel ,甚至還有硬式編碼連接埠號碼。用rackup,這些事情都變得可配置。! 但是用rackup,你需要用一個rackup設定檔來支援它。對於上一個例子,設定檔有點像:
1 2
|
# config.ru run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "Hello Rack!"]} |
只需要一行,按照約定,你應該使用.ru作為一個rackup設定檔的副檔名。支援它運行一個RackObject 你需要:
$ rackup config.ru
但是預設的,rackup會在9292連接埠啟動一個服務。但是你可以通過一個-p參數來指定這個連接埠號碼。你可以看更多的協助:
$ rackup --help