Hello Rack
從官網的介紹中提到:
Rack provides a minimal interface between webservers supporting Ruby and Ruby frameworks.
在開發 Ruby Web Framewrok 時有許多前置工作,必須對所支援的 Web Server 撰寫介面,然後解析 HTTP protocol,假如多支援一套 Web Server 這些工作又要再做一次,Rack 幫我們解決了重複性的工作,Rack 支援不同的 Server,將 HTTP request 與 response 包裝後,成為統一的 API 標準,不管 Web Server 是 WEBrick 、 Mongrel 或是 Unicorn ,Web Framework 都只需要對 Rack 溝通就行了,就像是如果要馬上精通各國語言(Web Server),吃個翻譯蒟蒻就萬事OK,Rack就是翻譯蒟蒻!!!
第一個 Rack application
使用 Rack 很容易就可以完成一個簡單的 Web Application,官方的文件中寫到:
The Rack application is an object that responds to the call method, taking the environment hash as a parameter, and returning an Array with three elements: status, headers and a body
舉例來說,這就是一個簡單的 Rack Application
但我們要讓它動起來~ 必須使用 Rack::Handler
,這是 Rack 連接 Web Server 的介面,讓我們可以把程式跑在 Server 上,Handler 可以連接不同的Http Server,如 Thin, WEBrick, FastCGI… (Handler列表),在這邊使用 Webrick
啟動 server
執行 ruby hello_rack.rb
,開啟瀏覽器 http://localhost:8080
,會看到以下畫面:
Response
實際上畫面的回應是來自於 call
這個方法的回傳值,Rack 的文件中定義回傳值必須是一個 Array
:
- Status code: 可以指定 200, 400, 302 等
- Http headers: HTTP 的標頭,型態需為
hash
,hash
的內容至少要指定content-type
,例:{"Content-Type" => "text/html"}
- Response body: 回傳的內容,此物件必須能夠回應
each
這個方法(使用 array 就可以了),如果他有多個 response body 則會由第一個元素開始輸出。
所以如果 call
回傳的是像這樣的內容:
打開 chrome console 來看:
就是這樣囉~
Request
可以看到 call(env)
這個方法傳入唯一的參數 env
,但在上一段的程式完全沒有用到參數 env
,實際上參數 env
就是 environment 的資訊,那environment 的資訊包含哪些呢?利用上一節的 response,我們可以把 environment 打開來看看裡頭有什麼。
執行結果:
雖然結果顯示的有點擁擠,但依稀可以看到 "PATH_INFO"=>"/"
、"QUERY_STRING"=>""
、"REQUEST_METHOD"=>"GET"
,沒錯,我們可以從environment拿到request的資訊,這就可以發揮想像做很多事啦,比如說簡單的做一個router讓不同的request顯示不同的內容。
完整的environment的資訊可以參考spec。
Excercise
作為練習,要來做一個稍微有點功能的應用程式啦,需求是這樣的,我可以下 http://locahost:8080/request_method
,去查詢該 environemtn
的參數,如果沒有子路徑的話,就回傳所有參數,回傳的參數必須要用 html
的 table
顯示(比較好看 :D),無此參數就回傳“查無結果”。
STEP
- 寫一個
convert_hash_to_table
的方法 - 將
"Content-Type" => "text/plain"
改為text/html
- 找到路徑
env['REQUEST_PATH']
- 判斷是否有此 environment 參數
- 輸出結果
後續發展
基本的rack就是這樣啦,下個相關的研究議題 什麼是Rack Middleware?、Rails中的Rack Middleware,改天介紹。