Golang中HttpRouter路由的使用詳解
httprouter
httprouter 是一個(gè)高性能、可擴(kuò)展的HTTP路由,上面我們列舉的net/http默認(rèn)路由的不足,都被httprouter 實(shí)現(xiàn),我們先用一個(gè)例子,認(rèn)識(shí)下 httprouter 這個(gè)強(qiáng)大的 HTTP 路由。
安裝:
go get -u github.com/julienschmidt/httprouter
在這個(gè)例子中,首先通過(guò)httprouter.New()生成了一個(gè)*Router路由指針,然后使用GET方法注冊(cè)一個(gè)適配/路徑的Index函數(shù),最后*Router作為參數(shù)傳給ListenAndServe函數(shù)啟動(dòng)HTTP服務(wù)即可。
package main import ( "log" "net/http" "github.com/julienschmidt/httprouter" ) func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { w.Write([]byte("Index")) } func main() { router := httprouter.New() router.GET("/", Index) log.Fatal(http.ListenAndServe(":8080", router)) }
httprouter 為所有的HTTP Method 提供了快捷的使用方式,只需要調(diào)用對(duì)應(yīng)的方法即可。
func (r *Router) GET(path string, handle Handle) { r.Handle("GET", path, handle) } func (r *Router) HEAD(path string, handle Handle) { r.Handle("HEAD", path, handle) } func (r *Router) OPTIONS(path string, handle Handle) { r.Handle("OPTIONS", path, handle) } func (r *Router) POST(path string, handle Handle) { r.Handle("POST", path, handle) } func (r *Router) PUT(path string, handle Handle) { r.Handle("PUT", path, handle) } func (r *Router) PATCH(path string, handle Handle) { r.Handle("PATCH", path, handle) } func (r *Router) DELETE(path string, handle Handle) { r.Handle("DELETE", path, handle) }
現(xiàn)代的API,基本上都是Restful API,httprouter提供的命名參數(shù)的支持,可以很方便的幫助我們開(kāi)發(fā)Restful API。比如我們?cè)O(shè)計(jì)的API/user/flysnow,這這樣一個(gè)URL,可以查看flysnow這個(gè)用戶(hù)的信息,如果要查看其他用戶(hù)的,比如zhangsan,我們只需要訪問(wèn)API/user/zhangsan即可。
URL包括兩種匹配模式:/user/:name精確匹配、/user/*name匹配所有的模式。
package main import ( "github.com/julienschmidt/httprouter" "net/http" "log" "fmt" ) func main() { router:=httprouter.New() router.GET("/MainData", func (w http.ResponseWriter,r *http.Request,_ httprouter.Params) { w.Write([]byte("default get")) }) router.POST("/MainData",func (w http.ResponseWriter,r *http.Request,_ httprouter.Params) { w.Write([]byte("default post")) }) //精確匹配 router.GET("/user/name",func (w http.ResponseWriter,r *http.Request,p httprouter.Params) { w.Write([]byte("user name:"+p.ByName("name"))) }) //匹配所有 router.GET("/employee/*name",func (w http.ResponseWriter,r *http.Request,p httprouter.Params) { w.Write([]byte("employee name:"+p.ByName("name"))) }) http.ListenAndServe(":8081", router) }
Handler處理鏈處理不同二級(jí)域名
package main import ( "fmt" "log" "net/http" "github.com/julienschmidt/httprouter" ) type HostMap map[string]http.Handler func (hs HostMap) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Println("222") //根據(jù)域名獲取對(duì)應(yīng)的Handler路由,然后調(diào)用處理(分發(fā)機(jī)制) if handler := hs[r.Host]; handler != nil { handler.ServeHTTP(w, r) } else { http.Error(w, "Forbidden", 403) } } func main() { userRouter := httprouter.New() userRouter.GET("/", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { w.Write([]byte("play")) }) dataRouter := httprouter.New() dataRouter.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { w.Write([]byte("tool")) }) //分別用于處理不同的二級(jí)域名 hs := make(HostMap) hs["user.localhost:12345"] = userRouter hs["data.localhost:12345"] = dataRouter log.Fatal(http.ListenAndServe(":12345", hs)) }
httprouter提供了很方便的靜態(tài)文件服務(wù),可以把一個(gè)目錄托管在服務(wù)器上,以供訪問(wèn)。
router.ServeFiles("/static/*filepath",http.Dir("./"))
使用ServeFiles需要注意的是,第一個(gè)參數(shù)路徑,必須要以/*filepath,因?yàn)橐@取我們要訪問(wèn)的路徑信息。
func (r *Router) ServeFiles(path string, root http.FileSystem) { if len(path) < 10 || path[len(path)-10:] != "/*filepath" { panic("path must end with /*filepath in path '" + path + "'") } fileServer := http.FileServer(root) r.GET(path, func(w http.ResponseWriter, req *http.Request, ps Params) { req.URL.Path = ps.ByName("filepath") fileServer.ServeHTTP(w, req) }) }
例子:
package main import ( "log" "net/http" "github.com/julienschmidt/httprouter" ) func main() { router := httprouter.New() //訪問(wèn)靜態(tài)文件 router.ServeFiles("/static/*filepath", http.Dir("./files")) log.Fatal(http.ListenAndServe(":8080", router)) }
httprouter 異常捕獲,httprouter允許使用者,設(shè)置PanicHandler用于處理HTTP請(qǐng)求中發(fā)生的panic。
package main import ( "fmt" "log" "net/http" "github.com/julienschmidt/httprouter" ) func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { panic("error") } func main() { router := httprouter.New() router.GET("/", Index) //捕獲異常 router.PanicHandler = func(w http.ResponseWriter, r *http.Request, v interface{}) { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "error:%s", v) } log.Fatal(http.ListenAndServe(":8080", router)) }
httprouter還有不少有用的小功能,比如對(duì)404進(jìn)行處理,我們通過(guò)設(shè)置Router.NotFound來(lái)實(shí)現(xiàn),我們看看Router這個(gè)結(jié)構(gòu)體的配置,可以發(fā)現(xiàn)更多有用的功能。
type Router struct { //是否通過(guò)重定向,給路徑自定加斜杠 RedirectTrailingSlash bool //是否通過(guò)重定向,自動(dòng)修復(fù)路徑,比如雙斜杠等自動(dòng)修復(fù)為單斜杠 RedirectFixedPath bool //是否檢測(cè)當(dāng)前請(qǐng)求的方法被允許 HandleMethodNotAllowed bool //是否自定答復(fù)OPTION請(qǐng)求 HandleOPTIONS bool //404默認(rèn)處理 NotFound http.Handler //不被允許的方法默認(rèn)處理 MethodNotAllowed http.Handler //異常統(tǒng)一處理 PanicHandler func(http.ResponseWriter, *http.Request, interface{}) }
到此這篇關(guān)于Golang中HttpRouter路由的使用詳解的文章就介紹到這了,更多相關(guān)Golang HttpRouter路由內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
構(gòu)建go鏡像實(shí)現(xiàn)過(guò)程全面講解
這篇文章主要為大家介紹了構(gòu)建go鏡像實(shí)現(xiàn)過(guò)程全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12一文帶你了解Go語(yǔ)言fmt標(biāo)準(zhǔn)庫(kù)輸出函數(shù)的使用
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中 fmt 標(biāo)準(zhǔn)庫(kù)輸出函數(shù)的使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)必會(huì)知識(shí)點(diǎn)總結(jié)
如果你是一個(gè)開(kāi)發(fā)人員,或多或少對(duì)樹(shù)型結(jié)構(gòu)都有一定的認(rèn)識(shí)。二叉樹(shù)作為樹(shù)的一種,是一種重要的數(shù)據(jù)結(jié)構(gòu),也是面試官經(jīng)??嫉臇|西。本文為大家總結(jié)了一些二叉樹(shù)必會(huì)知識(shí)點(diǎn),需要的可以參考一下2022-08-08Gin與Mysql實(shí)現(xiàn)簡(jiǎn)單Restful風(fēng)格API實(shí)戰(zhàn)示例詳解
這篇文章主要為大家介紹了Gin與Mysql實(shí)現(xiàn)簡(jiǎn)單Restful風(fēng)格API示例詳解,有需要的朋友可以借鑒參考下希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11詳解Go并發(fā)編程時(shí)如何避免發(fā)生競(jìng)態(tài)條件和數(shù)據(jù)競(jìng)爭(zhēng)
大家都知道,Go是一種支持并發(fā)編程的編程語(yǔ)言,但并發(fā)編程也是比較復(fù)雜和容易出錯(cuò)的。比如本篇分享的問(wèn)題:競(jìng)態(tài)條件和數(shù)據(jù)競(jìng)爭(zhēng)的問(wèn)題2023-04-04使用Gin框架返回JSON、XML和HTML數(shù)據(jù)
Gin是一個(gè)高性能的Go語(yǔ)言Web框架,它不僅提供了簡(jiǎn)潔的API,還支持快速的路由和中間件處理,在Web開(kāi)發(fā)中,返回JSON、XML和HTML數(shù)據(jù)是非常常見(jiàn)的需求,本文將介紹如何使用Gin框架來(lái)返回這三種類(lèi)型的數(shù)據(jù),需要的朋友可以參考下2024-08-08