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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

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

目錄【閱讀時間:約10分鐘】

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

一.概述

gorilla/mux程序包,是一個強大的url路由和調度器,它具有小巧但是穩定高效的特性。

不僅可以支持正則路由,還可以按照Method、header、host等信息匹配,可以從我們設定的路由表達式中提取出參數方便上層應用,而且完全兼容http.ServerMux。


二.對比: gorilla/mux與net/http DefaultServeMux

Go 官方標準庫 net/http 自帶的 DefaultServeMux 底層實現,通過 DefaultServeMux 提供的路由處理器雖然簡單易上手,但是存在很多不足,比如:

  • 不支持參數設定,例如 /user/:uid 這種泛類型匹配;
  • 對 REST 風格接口支持不友好,無法限制訪問路由的方法;
  • 對于擁有很多路由規則的應用,編寫大量路由規則非常繁瑣。

為此,我們可以使用第三方庫 gorilla/mux 提供的更加強大的路由處理器(mux 代表 HTTP request multiplexer,即 HTTP 請求多路復用器),和 http.ServeMux 實現原理一樣,gorilla/mux 提供的路由器實現類 mux.Router 也會匹配用戶請求與系統注冊的路由規則,然后將用戶請求轉發過去。

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

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



三.簡單使用

安裝程序包:

go get -u github.com/gorilla/mux

樣例①:
基于Golang的簡單web服務程序開發——CloudGo
主要的相關函數為NewServer函數與initRoutes函數:

// 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)  // 設置響應狀態碼為 200fmt.Fprintf(w, "Hello, World!")  // 發送響應到客戶端
}func main()  {r := mux.NewRouter()r.HandleFunc("/hello", sayHelloWorld)log.Fatal(http.ListenAndServe(":8080", r))
}

main 函數中的第一行顯式初始化了 mux.Router 作為路由器,然后在這個路由器中注冊路由規則,最后將這個路由器傳入 http.ListenAndServe 方法,整個調用過程和之前并無二致,因為我們前面說了,mux.Router 也實現了 Handler 接口。

運行這段代碼,在瀏覽器訪問 http://localhost:8080/hello,即可渲染出如下結果:

Hello, World!



四.源碼簡析

gorilla/mux源碼可分為context、mux、regex、route四個部分,在CloudGo項目開發過程中,我主要使用了NewRouter、HandleFunc和PathPrefix這三個函數。下面對這三個函數進行分析:

1.NewRouter函數

Router是一個結構體,如下:

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
}

調用NewRouter函數可用來實例化一個Router:

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

這里可以看見,它開辟了一個裝Route指針的map,然后默認該Router的KeepContextfalse,意思是在請求被處理完之后清除該請求的上下文。



2.HandleFunc函數

// 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函數,會發現其代碼只有幾行,其主要功能是使用URL的匹配器注冊新路由。

gorilla/mux的HandleFunc函數功能很強大,主要有以下功能:

設置路由的HTTP方法

限制路由處理器只處理指定的HTTP方法的請求:

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")

上面的就是一組可以響應具體HTTP方法的RESTful風格的接口的路由。

設置路由的域名

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

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

限制HTTP 方案

將請求處理程序可響應的HTTP方案限制為http或者https。

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

設置路徑前綴和子路由

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



3.PathPrefix函數

// 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函數源碼也只有幾行,它的功能只是簡單地增加URL的前綴,通常結合HandleFunc函數和Handler函數來使用。



五.References

  1. 基于 gorilla/mux 包實現路由定義和請求分發:基本使用
  2. gorilla/mux類庫解析
  3. Gorilla源碼分析之gorilla/mux源碼分析
  4. 從一個例子分析gorilla/mux源碼
  5. gorilla/mux官方GitHub

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。