Rack
Rack是一種介面,提供網站程式與應用程式或開發框架(Sinatra、Rails等)間的一種介面(interface)。
Rails本身就是一個Rack的大型應用程式。
Sinatra較輕量化的應用程式,不像純Rack。
Rack的期望規格
- 要有個物件,並有call的方法。
- 被call之後要回傳一個陣列,並且陣列裡要有三個元素。
- 狀態、Header、Body。
- HTTP狀態
簡易的Rack應用程式
- 建立目錄
- 進入該目錄
- 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"]]
}
在 CoolProgrammer 這個類別裡一樣要有 call 方法,它最後也是要回傳跟一般 Rack 程式一樣的三個元素。
要掛上這個 Middleware,是使用 use 這個方法。
在 use 的時候,它會自動把整個 Rack 程式當做第一個參數傳入,所以你可以看到在 CoolProgrammer 類別裡的 initialize 方法額外接收了一個參數。
如果希望可以再傳入其它的參數,可在類別的 initialize 方法中再加上額外的參數,在使用的時候就會變 use CoolProgrammer, “5xRuby”。
Middleware 之所以可以一個接一個的執行下去,主要靠的就是在 call 方法裡再繼續執行傳進來的那個物件的 call 方法。
Ruby on Rails其實也是一種Rack應用程式
- Rails專案裡會有config.ru檔案
可以使用
rails middleware
指令看一下目前的 Rails 用了哪些 MiddlewareRuby 實作的網站伺服器介面