12/17/2010

Rack Middleware Stack

Rack middleware針對Http要求與Http回覆進行過濾(filter)。換言之,Rack機制可撰寫自己filter用來控制或加強由Rack app所產生內容。Rack內部實作利用 pipeline design pattern,separation of concerns 觀念,因此可任易組合filter針對需求或你自行開發架構。

Rack內建許多處理Http相關的Filter,分成Authentication, Authorisation , Caching, Decoration, Monitor,...,所以基本上應該想得到都存在。

如何利用Rack::Builder建構middleware stack?

[code lang="bash"] vim config.ru [/code] [code lang="ruby"] app = Rack::Builder.new do use Rack::CommonLogger use Rack::ShowExceptions run lambda {|env| [200, { 'Content-Type' => 'text/plain', 'Content-Length' => '12'}, ["Hello World!"] ] } end [/code]

執行

[code lang="bash"] rackup -p 9292 config.ru [/code]

執行結果

[code] $ curl -i http://localhost:9292 HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 12 Server: WEBrick/1.3.1 (Ruby/1.9.2/2010-08-18) Date: Fri, 17 Dec 2010 07:46:31 GMT Connection: Keep-Alive Hello World! [/code]

Sequence Diagram

Sequence Diagram

所有filter (Rack::CommonLogger, Rack::ShowExceptions...) 都必須符合Rack 規範,經過Rack::Builder建立起一個Rack middleware stack ( chain ), 如何簡易撰寫產生rack middleware stack程式 :

[code lang="ruby"] class Builder def initialize(&block) @stack = [] self.instance_eval (&block) end def use(middleware) @stack << middleware end def run(app) @app = app end def to_app @stack.reverse.inject(@app) { |app, middleware| middleware.new(app)} end end [/code]

如果參考 Rack::Builder 多了URLMap處理 (後續),rack middleware如何執行及撰寫,熟悉Rack小架子理論上應該可以組出很好東西!

參考

No comments:

Post a Comment