golang之路由库gorilla/mux
gorilla/mux
是 gorilla Web 开发工具包中的路由管理库。gorilla Web 开发包是 Go 语言中辅助开发 Web 服务器的工具包。它包括 Web 服务器开发的各个方面,
有表单数据处理包gorilla/schema
,
有 websocket 通信包gorilla/websocket
,
有各种中间件的包gorilla/handlers
,
有 session 管理包gorilla/sessions
,
有安全的 cookie 包gorilla/securecookie
mux
有以下优势:
- 实现了标准的
http.Handler
接口,所以可以与net/http
标准库结合使用,非常轻量; - 可以根据请求的主机名、路径、路径前缀、协议、HTTP 首部、查询字符串和 HTTP 方法匹配处理器,还可以自定义匹配逻辑;
- 可以在主机名、路径和请求参数中使用变量,还可以为之指定一个正则表达式;
- 可以传入参数给指定的处理器让其构造出完整的 URL;
- 支持路由分组,方便管理和维护。
快速使用
本文代码使用 Go Modules。
创建目录并初始化:
$ mkdir -p gorilla/mux && cd gorilla/mux
$ go mod init github.com/darjun/go-daily-lib/gorilla/mux
安装gorilla/mux
库:
go get -u github.com/gorilla/gorilla/mux
下面我们编写一个管理图书信息的 Web 服务。图书由 ISBN 唯一标识,ISBN 意为国际标准图书编号(International Standard Book Number)。
首先定义图书的结构:
type Book struct { ISBN string `json:"isbn"` Name string `json:"name"` Authors []string `json:"authors"` Press string `json:"press"` PublishedAt string `json:"published_at"` } var ( mapBooks map[string]*Book slcBooks []*Book )
定义init()
函数,从文件中加载数据:
func init() { mapBooks = make(map[string]*Book) slcBooks = make([]*Book, 0, 1) data, err := ioutil.ReadFile("../data/books.json") if err != nil { log.Fatalf("failed to read book.json:%v", err) } err = json.Unmarshal(data, &slcBooks) if err != nil { log.Fatalf("failed to unmarshal books:%v", err) } for _, book := range slcBooks { mapBooks[book.ISBN] = book } }
然后是两个处理函数,分别用于返回整个列表和某一本具体的图书:
func BooksHandler(w http.ResponseWriter, r *http.Request) { enc := json.NewEncoder(w) enc.Encode(slcBooks) } func BookHandler(w http.ResponseWriter, r *http.Request) { book, ok := mapBooks[mux.Vars(r)["isbn"]] if !ok { http.NotFound(w, r) return } enc := json.NewEncoder(w) enc.Encode(book) }
注册处理器:
func main() { r := mux.NewRouter() r.HandleFunc("/", BooksHandler) r.HandleFunc("/books/{isbn}", BookHandler) http.Handle("/", r) log.Fatal(http.ListenAndServe(":8080", nil)) }
mux
的使用与net/http
非常类似。首先调用mux.NewRouter()
创建一个类型为*mux.Router
的路由对象,该路由对象注册处理器的方式与标准库的*http.ServeMux
完全相同,即调用HandleFunc()
方法注册类型为func(http.ResponseWriter, *http.Request)
的处理函数,调用Handle()
方法注册实现了http.Handler
接口的处理器对象。上面注册了两个处理函数,一个是显示图书信息列表,一个显示具体某本书的信息。
注意到路径/books/{isbn}
使用了变量,在{}
中间指定变量名,它可以匹配路径中的特定部分。在处理函数中通过mux.Vars(r)
获取请求r
的路由变量,返回map[string]string
,后续可以用变量名访问。如上面的BookHandler
中对变量isbn
的访问。
由于*mux.Router
也实现了http.Handler
接口,所以可以直接将它作为http.Handle("/", r)
的处理器对象参数注册。这里注册的是根路径/
,相当于把所有请求的处理都托管给了*mux.Router
。
最后还是http.ListenAndServe(":8080", nil)
开启一个 Web 服务器,等待接收请求。
更多参考: https://darjun.github.io/2021/07/19/godailylib/gorilla/mux/