使用gorilla/mux增強Go HTTP服務器的路由能力

今天這篇文章我們將會爲我們之前編寫的 HTTP服務器加上覆雜路由的功能以及對路由進行分組管理。在之前的文章《深入學習用 Go 編寫HTTP服務器》中詳細地講了使用 net/http進行路由註冊、監聽網絡連接、處理請求、安全關停服務的實現方法,使用起來非常方便。但是 net/http有一點做的不是非常好的是,它沒有提供類似 URL片段解析、路由參數綁定這樣的複雜路由功能。好在在 Go社區中有一個非常流行的 gorilla/mux包,它提供了對複雜路由功能的支持。在今天這篇文章中我們將探究如何用 gorilla/mux包來創建具有命名參數、 GET/POST處理、分組前綴、限制訪問域名的路由。

安裝gorilla/mux包

我們在之前寫的 HTTP服務的代碼根目錄,使用go get命令從GitHub安裝軟件包,如下所示:

go get github.com/gorilla/mux

《深入學習用 Go 編寫HTTP服務器》中我們介紹過路由註冊、匹配和最後處理函數的調用都是由 ServeMux(服務複用器)來完成的,而且我們還自己定義了複用器用以替換默認的 DefaultServeMux。同樣的 gorilla/mux包也是爲我們提供了一個複用器。這個複用器擁有很多功能用以提升編寫 Web應用的效率,而且與標準的 http.ServeMux兼容。

使用gorilla/mux包

創建路由器

可以像下面這樣創建一個路由器

router := mux.NewRouter()

會返回一個 mux.Router實例, mux.Router將傳入的請求與已註冊路由列表進行匹配,併爲與 URL或其他條件匹配的路由調用處理程序。主要特點是:

  • 可以根據URL主機,路徑,路徑前綴, Header頭、查詢值, HTTP方法進行路由匹配,或是使用自定義匹配器。
  • URL主機,路徑和查詢值可以是帶有可選正則表達式的變量。
  • 路由可以被用作子路由,只有父路由匹配後纔會嘗試匹配子路由。這對於定義路由組非常有用,路由組可以共享主機、路徑前綴、或者其他常見的屬性。
  • 它實現了http.Handler接口,因此與標準的 http.ServeMux完全兼容。

註冊路由處理程序

我們將之前程序裏自定義的服務複用器替換成上面創建好 mux.Router,併爲其註冊路由處理器。

type helloHandler struct{}
func (*helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     fmt.Fprintf(w,"Hello World")
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request){
	 fmt.Fprintf(w,"Welcome!")
}

func main() {
	router:= mux.NewRouter()
	router.Handle("/", &helloHandler{})
	router.HandleFunc("/welcome", WelcomeHandler)
	......
}

之前我們是用 http.Hanle, http.HandleFunc註冊處理程序的,這裏直接換成 router.Hanle和 router.HanleFunc即可,很方便。

定義帶命名參數的路由

使用 mux.Router的最大優勢是可以從請求 URL中提取分段,然後作爲命名參數傳入路由處理程序供使用。

接下來爲我們的程序註冊一個路由處理器,讓服務器能夠處理 URL爲 /names/Gorge/countries/NewZealand的請求:

router.HandleFunc("/names/{name}/countries/{country}", func (writer http.ResponseWriter, request *http.Request) {
......
})

接下來在處理函數中使用 mux.Vars()函數從這些 URL分段中獲取數據。該函數以 http.Request爲參數並返回一個 URL分段名爲鍵,提取的數據爲值的字典。
在這裏插入圖片描述
讓服務器使用我們創建的路由器

這個設置很簡單,如果沒有自定義 http.Server對象,使用 http.ListenAndServe(":8000",router),使用自己定義的`http.Server 對象時則是:
在這裏插入圖片描述
這個和我們把自定義的服務複用器傳遞給 http.Server沒有任何區別。

改造完後我們之前寫的 HTTP服務器就可以根據具體的 URL 動態地構造響應。關鍵字回覆 gohttp02可獲得完整的源代碼

其他gorilla/mux路由器的常用功能

設置路由的HTTP方法

限制路由處理器只處理指定的 HTTP方法的請求:
在這裏插入圖片描述
上面的就是一組可以響應具體 HTTP方法的 RESTful風格的接口的路由。

設置路由的域名

限制路由處理器只處理訪問指定域名加路由的請求:

router.HandleFunc("/books/{title}", BookHandler).Host("www.mybookstore.com")

限制HTTP方案

將請求處理程序可響應的 HTTP方案限制爲 http或者 https。
在這裏插入圖片描述
設置路徑前綴和子路由在這裏插入圖片描述
使用gorilla/mux改進我們的HTTP服務器

接下來我們使用 gorilla/mux對我們之前寫的 HTTP服務器做一下改進,之前我們所有程序都放在了 main.go中,現在我們的程序還很小,所以我們先不把項目目錄規劃的太複雜,先通過文件做下簡單的職責劃分,新建兩個文件 router.go和 handler.go分別用來存放路由註冊的邏輯和路由對應的處理器函數,兩個文件的示例內容如下。

handler.go:
在這裏插入圖片描述
router.go:
在這裏插入圖片描述
在 router.go中我們將路由分爲 index和 user兩組,在兩個路由組上分別定義路由。將這部分封裝在一個導出函數 RegisterRoutes供調用。這樣即使以後路由註冊的程序要放到單獨的目錄裏也可以供外部調用。

整理完後我們的 main.go中就會變的很簡潔:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章