Rack

  • Rack是一種介面,提供網站程式與應用程式或開發框架(Sinatra、Rails等)間的一種介面(interface)。

  • Rails本身就是一個Rack的大型應用程式。

  • Sinatra較輕量化的應用程式,不像純Rack。

Rack的期望規格

  1. 要有個物件,並有call的方法。
  2. 被call之後要回傳一個陣列,並且陣列裡要有三個元素。
  3. 狀態、Header、Body。

  • HTTP狀態


簡易的Rack應用程式

  1. 建立目錄
  2. 進入該目錄
  3. rackup ``` kuei:~ abc$ mkdir rack-demo kuei:~ abc$ cd rack-demo kuei:rack-demo abc$ rackup

configuration /Users/abc/rack-demo/config.ru not found


> 出現異常,並要求config.ru檔案
 
> 而在此處的ru為(rackup),這時需要至編輯器建立config.ru檔案,並編寫一段程式


### 使用Proc物件給Rack執行
 
```ruby=
run Proc.new {
  [200, { "Content-Type" => "text/html" }, ["Hello, Rack"]]
}

Rack期望要有一個可以call的物件,所以這裡做了一個 Proc物件給它執行((因為Proc本身就有內建call方法))。

執行後要回傳一個陣列,所以直接在Proc物件裡放了一個陣列,當它被call之後會回傳。

回到終端機上並再次輸入: rackup

kuei:rack-demo abc$ rackup

configuration /Users/abc/rack-demo/config.ru not found
kuei:rack-demo abc$ rackup
Puma starting in single mode...
* Version 4.3.1 (ruby 2.6.3-p62), codename: Mysterious Traveller
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://127.0.0.1:9292
* Listening on tcp://[::1]:9292
Use Ctrl-C to stop

開啟瀏覽器連到 http://localhost:9292/

可以順利出現Rack的應用程式。

如果想要改變預設的 Port 9292,可使用參數 rackup -p 3000,就會在 Port 3000 啟動服務。


使用Ruby的類別給Rack執行

class App
  def call(env)
    [200, { "Content-Type" => "text/html" }, ["Hello, Rack from Class"]]
  end
end

run App.new

Rack 在呼叫 call 方法的時候會把環境參數也傳進來,所以在上面這個例子中,call 方法需要加上個參數,否則會發生錯誤。

可以再次順利出現Rack的應用程式

⁜ 使用Proc物件或方法對Rack並無差異,因為只要有call的功能就好,不過使用方法可以有更大的彈性,因為可以應用物件導向的特性。


Middleware(中介軟體)

  • 在 Rack 執行的過程中,還可以在中間安插一些流程,我們稱之中介軟體(Middleware)

  • Middleware 的規格也很單純,就跟一般的 Rack 要求一樣,要可以回應 call 方法。

class CoolProgrammer
  def initialize(app, who = "5xRuby")
    @app = app
    @who = who
  end

  def call(env)
    status, headers, body = @app.call(env)
    body << "<br />Powered by #{@who}!"

    [status, headers, body]
  end
end

use CoolProgrammer, "5xRuby"

run Proc.new {
  [200, { "Content-Type" => "text/html" }, ["Hello, Rack"]]
}
  1. 在 CoolProgrammer 這個類別裡一樣要有 call 方法,它最後也是要回傳跟一般 Rack 程式一樣的三個元素。

  2. 要掛上這個 Middleware,是使用 use 這個方法。

  3. 在 use 的時候,它會自動把整個 Rack 程式當做第一個參數傳入,所以你可以看到在 CoolProgrammer 類別裡的 initialize 方法額外接收了一個參數。

  4. 如果希望可以再傳入其它的參數,可在類別的 initialize 方法中再加上額外的參數,在使用的時候就會變 use CoolProgrammer, “5xRuby”。

  5. Middleware 之所以可以一個接一個的執行下去,主要靠的就是在 call 方法裡再繼續執行傳進來的那個物件的 call 方法。


Ruby on Rails其實也是一種Rack應用程式

  • Rails專案裡會有config.ru檔案
  • 可以使用 rails middleware 指令看一下目前的 Rails 用了哪些 Middleware

  • Ruby 實作的網站伺服器介面