rack學習1

weixin_33728268發表於2015-08-24

rack是ruby伺服器和rack應用程式之間的一個框架,rails,sinatra都是基
於rack構建的,都屬於rack應用程式。

rack提供了一個標準的介面,用於與伺服器進行互動。標準的rack程式
是一個可以響應call的物件,可以是物件、Proc、lambda甚至是method,
它接收env引數(環境物件),返回一個陣列,陣列包括:

  • 狀態(status),http響應狀態碼
  • 可以是hash,為http的header資訊
  • 擁有each方法的物件,each返回字串

rack通過中介軟體來進行擴充套件,即對原始的rack程式進行裝飾,
在原有返回陣列的基礎上進一步處理,並返回rack物件

簡單的rack程式

require 'rack'

app = lambda{|env|[200,{},["hello from rack"]]}
Rack::Handler::WEBrick.run app

使用中介軟體的rack程式

require 'rack'

class Decorator
  def initialize(app)
    @app = app
  end
  def call(env)
    status, headers, body = @app.call(env)
    new_body = "from middleware input <br/>"
    body.each{|str| new_body << str}
    headers['Content-Length'] = new_body.bytesize.to_s
    [status, headers, [new_body]]
  end
end

app = lambda{|env|[200,{},["hello from rack"]]}
Rack::Handler::WEBrick.run Decorator.new(app)

上面使用中介軟體的方法在使用多個時容易混亂,rack有一個Builder類可以有效管理
使用如下

require 'rack'
require 'decorator'

app = Rack::Builder.new{
  use Rack::ContentLength
  use Decorator
  run lambda {|env| [200, {"Content-Type"=>"text/html"}, ["hello world"]]}
}.to_app
Rack::Handler::WEBrick.run app

使用Rack::Builder的map方法,可以建立有路由的rack程式

require 'rack'
app = Rack::Builder.new {
  map '/hello' do
run lambda {|env| [200, {"Content-Type" => "text/html"}, ["hello"]] } end
map '/world' do
run lambda {|env| [200, {"Content-Type" => "text/html"}, ["world"]] }
end
map '/' do
run lambda {|env| [200, {"Content-Type" => "text/html"}, ["all"]] } end
}.to_app
Rack::Handler::WEBrick.run app, :Port => 3000

由於rails的全棧性,rack中介軟體很多,在一些高併發但業務簡單的網站或api使用時
響應時間過長,在這種情況下可以考慮使用rack或者sinatra。

轉載請註明出處:me.angry-arthas.com/blog/2015/09/06/rakexue-xi-1/