go web: 3 中介軟體和路由
阿新 • • 發佈:2019-01-02
中介軟體
中介軟體的本質來看,就是在執行handler的前(後)先執行一個自定義的handler而已。那問題變成,go web中,每個handler是怎麼執行的。
答案在mux := http.NewServeMux()
中,稍微閱讀下原始碼,我們就能得出,mux物件中有個ServeHTTP(w, r)
方法。這就祕密所在。
根據go的鴨子型別特性,我們完全可以實現一個結構,然後讓它擁有ServeHTTP(w, r)
方法。把這個結構替換掉http.Server
物件中的Handler
,就能自定義hander的執行。既然都能控制handler運行了,中介軟體什麼的還不是小case。
然而還能更簡單,可愛的go語言還在http包中,提供了一個http.HandlerFunc(ourFunc)
func(w http.ResponseWriter, r *http.Request)
的函式轉化為一個handler,沒錯,就是上面mux相同的型別。 要實現自己的mux,可以只是一個簡單的函式:
// myHost 做中介軟體
func myHost(handler http.Handler) http.Handler {
ourFunc := func(w http.ResponseWriter, r *http.Request) {
//記錄時間
start := time.Now()
handler.ServeHTTP (w, r)
logger.Infoln(
fmt.Sprintf("%s %s %s", r.Method, r.URL, time.Now().Sub(start)))
}
return http.HandlerFunc(ourFunc)
}
這個“記錄時間”的操作,不就是最簡單的中介軟體嗎?
main.go中的呼叫則改成:
mux := http.NewServeMux()
mh := myHost(mux)
server :=
http.Server{
Addr: fmt.Sprintf (":%d", options.GetInt("port")),
Handler: mh,
ReadTimeout: 3 * time.Second,
WriteTimeout: 5 * time.Second,
}
// 開始新增路由
mux.HandleFunc("/hi", test.SayHello)
server.ListenAndServe()
路由
既然我們能通過hack ServeHTTP
來控制handler的呼叫,那實現路由還不是順水推舟。
在server.go中看看mux.ServeHTTP
和mux.handler
這兩個函式原始碼,這個簡單而蛋疼的預設路由就躍然紙上。
對於路由,我們沒必要自己寫ServeHttp和match規則,因為太麻煩了。
所以,我們google下 httprouter
這個包。輪子都造好了。