欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語(yǔ)言HttpRouter路由使用方法詳解

 更新時(shí)間:2022年04月18日 10:52:04   作者:駿馬金龍  
這篇文章主要介紹了Go語(yǔ)言HttpRouter路由使用方法詳解,需要的朋友可以參考下

HttpRouter是一個(gè)輕量級(jí)但卻非常高效的multiplexer。手冊(cè):

https://godoc.org/github.com/julienschmidt/httprouter

https://github.com/julienschmidt/httprouter

用法示例

package main

import (
    "fmt"
    "github.com/julienschmidt/httprouter"
    "net/http"
    "log"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}

func main() {
    router := httprouter.New()
    router.GET("/", Index)
    router.GET("/hello/:name", Hello)

    log.Fatal(http.ListenAndServe(":8080", router))
}

首先執(zhí)行:

go get github.com/julienschmidt/httprouter

然后再啟動(dòng)web服務(wù):

go run xxx.go

和http包的ServeMux用法其實(shí)很類(lèi)似。上面定義了兩個(gè)httprouter中的handle,類(lèi)似于http包中的http.HandlerFunc類(lèi)型,具體的對(duì)應(yīng)關(guān)系后文會(huì)解釋?zhuān)灰J(rèn)為它是handler,是處理對(duì)應(yīng)請(qǐng)求的就行了。然后使用New()方法創(chuàng)建了實(shí)例,并使用GET()方法為兩個(gè)模式注冊(cè)了對(duì)應(yīng)的handler。

需要注意的是,第二個(gè)模式"/hello/:name",它可以用來(lái)做命名匹配,類(lèi)似于正則表達(dá)式的命名捕獲分組。后面會(huì)詳細(xì)解釋用法。

httprouter用法說(shuō)明

Variables
func CleanPath(p string) string
type Handle
type Param
type Params
	func ParamsFromContext(ctx context.Context) Params
	func (ps Params) ByName(name string) string
type Router
	func New() *Router
	func (r *Router) DELETE(path string, handle Handle)
	func (r *Router) GET(path string, handle Handle)
	func (r *Router) HEAD(path string, handle Handle)
	func (r *Router) Handle(method, path string, handle Handle)
	func (r *Router) Handler(method, path string, handler http.Handler)
	func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc)
	func (r *Router) Lookup(method, path string) (Handle, Params, bool)
	func (r *Router) OPTIONS(path string, handle Handle)
	func (r *Router) PATCH(path string, handle Handle)
	func (r *Router) POST(path string, handle Handle)
	func (r *Router) PUT(path string, handle Handle)
	func (r *Router) ServeFiles(path string, root http.FileSystem)
	func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

type Handle

httprouter中的Handle類(lèi)似于http.HandlerFunc,只不過(guò)它支持第三個(gè)參數(shù)Params。

type Handle func(http.ResponseWriter, *http.Request, Params)
    Handle is a function that can be registered to a route to handle HTTP
    requests. Like http.HandlerFunc, but has a third parameter for the values of
    wildcards (variables).

例如前面示例中的Index()和Hello()都是Handle類(lèi)型的實(shí)例。

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}

注冊(cè)handler

httprouter.Router類(lèi)型類(lèi)似于http包中的ServeMux,它實(shí)現(xiàn)了http.Handler接口,所以它是一個(gè)http.Handler。它可以將請(qǐng)求分配給注冊(cè)好的handler。

type Router struct {}
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

除此之外,Router提供了不少方法,用來(lái)指示如何為路徑注冊(cè)handler。

func (r *Router) Handle(method, path string, handle Handle)
func (r *Router) Handler(method, path string, handler http.Handler)
func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc)

httprouter.Handle()用于為路徑注冊(cè)指定的Handle,而httprouter.Handle對(duì)應(yīng)于http.HandlerFunc,所以是直接將Handle類(lèi)型的函數(shù)綁定到指定路徑上。同時(shí),它還可以指定http方法:GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS。

這些方法還有對(duì)應(yīng)的各自縮寫(xiě):

func (r *Router) DELETE(path string, handle Handle)
func (r *Router) GET(path string, handle Handle)
func (r *Router) HEAD(path string, handle Handle)
func (r *Router) OPTIONS(path string, handle Handle)
func (r *Router) PATCH(path string, handle Handle)
func (r *Router) POST(path string, handle Handle)
func (r *Router) PUT(path string, handle Handle)

例如,Get()等價(jià)于route.Handle("GET", path, handle)。

例如上面的示例中,為兩個(gè)路徑注冊(cè)了各自的httprouter.Handle函數(shù)。

router := httprouter.New()
router.GET("/", Index)
router.GET("/hello/:name", Hello)

Handler()方法是直接為指定http方法和路徑注冊(cè)http.Handler;HandlerFunc()方法則是直接為指定http方法和路徑注冊(cè)http.HandlerFunc。

Param相關(guān)

type Param struct {
    Key   string
    Value string
}
Param is a single URL parameter, consisting of a key and a value.

type Params []Param
Params is a Param-slice, as returned by the router. The slice is ordered, the first URL parameter is also the first slice value. It is therefore safe to read values by the index.

func (ps Params) ByName(name string) string
ByName returns the value of the first Param which key matches the given name. If no matching Param is found, an empty string is returned.

Param類(lèi)型是key/value型的結(jié)構(gòu),每個(gè)分組捕獲到的值都會(huì)保存為此類(lèi)型。正如前面的示例中:

router.GET("/hello/:name", Hello)

這里的:name就是key,當(dāng)請(qǐng)求的URL路徑為/hello/abc,則key對(duì)應(yīng)的value為abc。也就是說(shuō)保存了一個(gè)Param實(shí)例:

Param{
	Key: "name",
	Value: "abc",
}

更多的匹配用法稍后解釋。

Params是Param的slice。也就是說(shuō),每個(gè)分組捕獲到的key/value都存放在這個(gè)slice中。

ByName(str)方法可以根據(jù)Param的Key檢索已經(jīng)保存在slice中的Param的Value。正如示例中:

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}

router.GET("/hello/:name", Hello)

這里ByName("name")將檢索保存在slice中,Key="name"的Param,且返回這個(gè)Param中的Value。

由于Params是slice結(jié)構(gòu),除了ByName()方法可以檢索key/value,通過(guò)slice的方法也可以直接檢索:

ps[0].Key
ps[0].Value

路徑匹配規(guī)則

httprouter要為路徑注冊(cè)handler的適合,路徑可以進(jìn)行命名捕獲。有兩種命名捕獲的方式:

Syntax    Type
:name     named parameter
*name     catch-all parameter

其中:name的捕獲方式是匹配內(nèi)容直到下一個(gè)斜線或者路徑的結(jié)尾。例如要為如下路徑注冊(cè)handler:

Path: /blog/:category/:post

當(dāng)請(qǐng)求路徑為:

/blog/go/request-routers            match: category="go", post="request-routers"
/blog/go/request-routers/           no match, but the router would redirect
/blog/go/                           no match
/blog/go/request-routers/comments   no match

*name的捕獲方式是從指定位置開(kāi)始(包含前綴"/")匹配到結(jié)尾:

Path: /files/*filepath

/files/                             match: filepath="/"
/files/LICENSE                      match: filepath="/LICENSE"
/files/templates/article.html       match: filepath="/templates/article.html"
/files                              no match, but the router would redirect

再解釋下什么時(shí)候會(huì)進(jìn)行重定向。在Router類(lèi)型中,第一個(gè)字段控制尾隨斜線的重定向操作:

type Router struct {
    RedirectTrailingSlash bool
	...
}

如果請(qǐng)求的URL路徑包含或者不包含尾隨斜線時(shí),但在注冊(cè)的路徑上包含了或沒(méi)有包含"/"的目標(biāo)上定義了handler,但是會(huì)進(jìn)行301重定向。簡(jiǎn)單地說(shuō),不管URL是否帶尾隨斜線,只要注冊(cè)路徑不存在,但在去掉尾隨斜線或加上尾隨斜線的路徑上定義了handler,就會(huì)自動(dòng)重定向。

例如注冊(cè)路徑為/foo,請(qǐng)求路徑為/foo/,會(huì)重定向。

下面還有幾種會(huì)重定向的情況:

注冊(cè)路徑:/blog/:category/:post
請(qǐng)求URL路徑:/blog/go/request-routers/

注冊(cè)路徑:/blog/:category
請(qǐng)求URL路徑:/blog/go

注冊(cè)路徑:/files/*filepath
請(qǐng)求URL路徑:/files

Lookup()

func (r *Router) Lookup(method, path string) (Handle, Params, bool)

Lookup根據(jù)method+path檢索對(duì)應(yīng)的Handle,以及Params,并可以通過(guò)第三個(gè)返回值判斷是否會(huì)進(jìn)行重定向。

更多關(guān)于Go語(yǔ)言HttpRouter路由使用方法詳解請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

  • Go語(yǔ)言中調(diào)用外部命令的方法總結(jié)

    Go語(yǔ)言中調(diào)用外部命令的方法總結(jié)

    在工作中,我們時(shí)不時(shí)地會(huì)需要在Go中調(diào)用外部命令。本文為大家總結(jié)了Go語(yǔ)言中調(diào)用外部命令的幾種姿勢(shì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-11-11
  • 詳解Golang如何優(yōu)雅的終止一個(gè)服務(wù)

    詳解Golang如何優(yōu)雅的終止一個(gè)服務(wù)

    后端服務(wù)通常會(huì)需要?jiǎng)?chuàng)建子協(xié)程來(lái)進(jìn)行相應(yīng)的作業(yè),但進(jìn)程接受到終止信號(hào)或正常結(jié)束時(shí),并沒(méi)有判斷或等待子協(xié)程執(zhí)行結(jié)束,下面這篇文章主要給大家介紹了關(guān)于Golang如何優(yōu)雅的終止一個(gè)服務(wù)的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Golang中函數(shù)的使用方法詳解

    Golang中函數(shù)的使用方法詳解

    這篇文章主要詳細(xì)介紹了Golang中函數(shù)的使用方法,文中有詳細(xì)的示例代碼,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-05-05
  • go語(yǔ)言實(shí)現(xiàn)mqtt協(xié)議的實(shí)踐

    go語(yǔ)言實(shí)現(xiàn)mqtt協(xié)議的實(shí)踐

    MQTT是一個(gè)基于客戶(hù)端-服務(wù)器的消息發(fā)布/訂閱傳輸協(xié)議。本文主要介紹了go語(yǔ)言實(shí)現(xiàn)mqtt協(xié)議的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Go語(yǔ)言編程實(shí)現(xiàn)支持六種級(jí)別的日志庫(kù)?

    Go語(yǔ)言編程實(shí)現(xiàn)支持六種級(jí)別的日志庫(kù)?

    這篇文章主要為大家介紹了使用Golang編寫(xiě)一個(gè)支持六種級(jí)別的日志庫(kù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Go工具鏈之go tool cover使用方法和示例詳解

    Go工具鏈之go tool cover使用方法和示例詳解

    go tool cover是Go工具鏈中的一個(gè)命令,作用是分析測(cè)試用例的代碼覆蓋率,本文將對(duì)go tool cover 作用,使用方法和使用場(chǎng)景作一個(gè)簡(jiǎn)單的介紹,感興趣的同學(xué)可以參考閱讀一下
    2023-07-07
  • Go語(yǔ)言二維數(shù)組的傳參方式

    Go語(yǔ)言二維數(shù)組的傳參方式

    這篇文章主要介紹了Go語(yǔ)言二維數(shù)組的傳參方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • go語(yǔ)言中iota和左移右移的使用說(shuō)明

    go語(yǔ)言中iota和左移右移的使用說(shuō)明

    這篇文章主要介紹了go語(yǔ)言中iota和左移右移的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • 詳解golang中的method

    詳解golang中的method

    這篇文章主要介紹了golang中的method的相關(guān)資料,幫助大家更好的理解和使用golang,感興趣的朋友可以了解下
    2021-01-01
  • Go實(shí)現(xiàn)線程池(工作池)的兩種方式實(shí)例詳解

    Go實(shí)現(xiàn)線程池(工作池)的兩種方式實(shí)例詳解

    這篇文章主要介紹了Go實(shí)現(xiàn)線程池(工作池)的兩種方式實(shí)例詳解,需要的朋友可以參考下
    2022-04-04

最新評(píng)論