日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

發(fā)布時(shí)間:2023/11/28 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄【閱讀時(shí)間:約10分鐘】

  • 一.概述
  • 二.對(duì)比: gorilla/mux與net/http DefaultServeMux
  • 三.簡(jiǎn)單使用
  • 四.源碼簡(jiǎn)析
    • 1.NewRouter函數(shù)
    • 2.HandleFunc函數(shù)
      • 設(shè)置路由的HTTP方法
      • 設(shè)置路由的域名
      • 限制HTTP 方案
      • 設(shè)置路徑前綴和子路由
    • 3.PathPrefix函數(shù)
  • 五.References

一.概述

gorilla/mux程序包,是一個(gè)強(qiáng)大的url路由和調(diào)度器,它具有小巧但是穩(wěn)定高效的特性。

不僅可以支持正則路由,還可以按照Method、header、host等信息匹配,可以從我們?cè)O(shè)定的路由表達(dá)式中提取出參數(shù)方便上層應(yīng)用,而且完全兼容http.ServerMux。


二.對(duì)比: gorilla/mux與net/http DefaultServeMux

Go 官方標(biāo)準(zhǔn)庫(kù) net/http 自帶的 DefaultServeMux 底層實(shí)現(xiàn),通過(guò) DefaultServeMux 提供的路由處理器雖然簡(jiǎn)單易上手,但是存在很多不足,比如:

  • 不支持參數(shù)設(shè)定,例如 /user/:uid 這種泛類型匹配;
  • 對(duì) REST 風(fēng)格接口支持不友好,無(wú)法限制訪問(wèn)路由的方法;
  • 對(duì)于擁有很多路由規(guī)則的應(yīng)用,編寫大量路由規(guī)則非常繁瑣。

為此,我們可以使用第三方庫(kù) gorilla/mux 提供的更加強(qiáng)大的路由處理器(mux 代表 HTTP request multiplexer,即 HTTP 請(qǐng)求多路復(fù)用器),和 http.ServeMux 實(shí)現(xiàn)原理一樣,gorilla/mux 提供的路由器實(shí)現(xiàn)類 mux.Router 也會(huì)匹配用戶請(qǐng)求與系統(tǒng)注冊(cè)的路由規(guī)則,然后將用戶請(qǐng)求轉(zhuǎn)發(fā)過(guò)去。

mux.Router 主要具備以下特性:

  • 實(shí)現(xiàn)了 http.Handler 接口,所以和 http.ServeMux 完全兼容;
  • 可以基于 URL 主機(jī)、路徑、前綴、scheme、請(qǐng)求頭、請(qǐng)求參數(shù)、請(qǐng)求方法進(jìn)行路由匹配;
  • URL 主機(jī)、路徑、查詢字符串支持可選的正則匹配;
  • 支持構(gòu)建或反轉(zhuǎn)已注冊(cè)的 URL 主機(jī),以便維護(hù)對(duì)資源的引用;
  • 支持路由嵌套(類似 Laravel 中的路由分組),以便不同路由可以共享通用條件,比如主機(jī)、路徑前綴等。



三.簡(jiǎn)單使用

安裝程序包:

go get -u github.com/gorilla/mux

樣例①:
基于Golang的簡(jiǎn)單web服務(wù)程序開(kāi)發(fā)——CloudGo
主要的相關(guān)函數(shù)為NewServer函數(shù)與initRoutes函數(shù):

// NewServer configures and returns a Server.
func NewServer() *negroni.Negroni {formatter := render.New(render.Options{Directory:  "templates",Extensions: []string{".html"},IndentJSON: true,})n := negroni.Classic()mx := mux.NewRouter()initRoutes(mx, formatter)n.UseHandler(mx)return n
}func initRoutes(mx *mux.Router, formatter *render.Render) {webRoot := os.Getenv("WEBROOT")if len(webRoot) == 0 {if root, err := os.Getwd(); err != nil {panic("Could not retrive working directory")} else {webRoot = root//fmt.Println(root)}}mx.HandleFunc("/api/test", apiTestHandler(formatter)).Methods("GET")mx.HandleFunc("/", homeHandler(formatter)).Methods("GET")mx.HandleFunc("/user", userHandler).Methods("POST")mx.PathPrefix("/").Handler(http.FileServer(http.Dir(webRoot + "/assets/")))
}

樣例②:

package mainimport ("fmt""github.com/gorilla/mux""log""net/http"
)func sayHelloWorld(w http.ResponseWriter, r *http.Request)  {w.WriteHeader(http.StatusOK)  // 設(shè)置響應(yīng)狀態(tài)碼為 200fmt.Fprintf(w, "Hello, World!")  // 發(fā)送響應(yīng)到客戶端
}func main()  {r := mux.NewRouter()r.HandleFunc("/hello", sayHelloWorld)log.Fatal(http.ListenAndServe(":8080", r))
}

main 函數(shù)中的第一行顯式初始化了 mux.Router 作為路由器,然后在這個(gè)路由器中注冊(cè)路由規(guī)則,最后將這個(gè)路由器傳入 http.ListenAndServe 方法,整個(gè)調(diào)用過(guò)程和之前并無(wú)二致,因?yàn)槲覀兦懊嬲f(shuō)了,mux.Router 也實(shí)現(xiàn)了 Handler 接口。

運(yùn)行這段代碼,在瀏覽器訪問(wèn) http://localhost:8080/hello,即可渲染出如下結(jié)果:

Hello, World!



四.源碼簡(jiǎn)析

gorilla/mux源碼可分為context、mux、regex、route四個(gè)部分,在CloudGo項(xiàng)目開(kāi)發(fā)過(guò)程中,我主要使用了NewRouter、HandleFunc和PathPrefix這三個(gè)函數(shù)。下面對(duì)這三個(gè)函數(shù)進(jìn)行分析:

1.NewRouter函數(shù)

Router是一個(gè)結(jié)構(gòu)體,如下:

type Router struct {// Configurable Handler to be used when no route matches.NotFoundHandler http.Handler// Configurable Handler to be used when the request method does not match the route.MethodNotAllowedHandler http.Handler// Parent route, if this is a subrouter.parent parentRoute// Routes to be matched, in order.routes []*Route// Routes by name for URL building.namedRoutes map[string]*Route// See Router.StrictSlash(). This defines the flag for new routes.strictSlash bool// See Router.SkipClean(). This defines the flag for new routes.skipClean bool// If true, do not clear the request context after handling the request.// This has no effect when go1.7+ is used, since the context is stored// on the request itself.KeepContext bool// see Router.UseEncodedPath(). This defines a flag for all routes.useEncodedPath bool
}

調(diào)用NewRouter函數(shù)可用來(lái)實(shí)例化一個(gè)Router:

// NewRouter returns a new router instance.
func NewRouter() *Router {return &Router{namedRoutes: make(map[string]*Route), KeepContext: false}
}

這里可以看見(jiàn),它開(kāi)辟了一個(gè)裝Route指針的map,然后默認(rèn)該Router的KeepContextfalse,意思是在請(qǐng)求被處理完之后清除該請(qǐng)求的上下文。



2.HandleFunc函數(shù)

// HandleFunc registers a new route with a matcher for the URL path.
// See Route.Path() and Route.HandlerFunc().
func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,*http.Request)) *Route {return r.NewRoute().Path(path).HandlerFunc(f)
}

若只觀察HandleFunc函數(shù),會(huì)發(fā)現(xiàn)其代碼只有幾行,其主要功能是使用URL的匹配器注冊(cè)新路由。

gorilla/mux的HandleFunc函數(shù)功能很強(qiáng)大,主要有以下功能:

設(shè)置路由的HTTP方法

限制路由處理器只處理指定的HTTP方法的請(qǐng)求:

router.HandleFunc("/books/{title}", CreateBook).Methods("POST")
router.HandleFunc("/books/{title}", ReadBook).Methods("GET")
router.HandleFunc("/books/{title}", UpdateBook).Methods("PUT")
router.HandleFunc("/books/{title}", DeleteBook).Methods("DELETE")

上面的就是一組可以響應(yīng)具體HTTP方法的RESTful風(fēng)格的接口的路由。

設(shè)置路由的域名

限制路由處理器只處理訪問(wèn)指定域名加路由的請(qǐng)求:

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

限制HTTP 方案

將請(qǐng)求處理程序可響應(yīng)的HTTP方案限制為http或者https

router.HandleFunc("/secure", SecureHandler).Schemes("https")
router.HandleFunc("/insecure", InsecureHandler).Schemes("http")

設(shè)置路徑前綴和子路由

bookrouter := router.PathPrefix("/books").Subrouter()
bookrouter.HandleFunc("/", AllBooks)
bookrouter.HandleFunc("/{title}", GetBook)



3.PathPrefix函數(shù)

// PathPrefix registers a new route with a matcher for the URL path prefix.
// See Route.PathPrefix().
func (r *Router) PathPrefix(tpl string) *Route {return r.NewRoute().PathPrefix(tpl)
}

PathPrefix函數(shù)源碼也只有幾行,它的功能只是簡(jiǎn)單地增加URL的前綴,通常結(jié)合HandleFunc函數(shù)和Handler函數(shù)來(lái)使用。



五.References

  1. 基于 gorilla/mux 包實(shí)現(xiàn)路由定義和請(qǐng)求分發(fā):基本使用
  2. gorilla/mux類庫(kù)解析
  3. Gorilla源碼分析之gorilla/mux源碼分析
  4. 從一個(gè)例子分析gorilla/mux源碼
  5. gorilla/mux官方GitHub

總結(jié)

以上是生活随笔為你收集整理的【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。