简介
gorilla/mux
是 gorilla Web 开发工具包中的路由管理库。gorilla Web 开发包是 Go 语言中辅助开发 Web 服务器的工具包。它包括 Web 服务器开发的各个方面,有表单数据处理包gorilla/schema
,有 websocket 通信包gorilla/websocket
,有各种中间件的包gorilla/handlers
,有 session 管理包gorilla/sessions
,有安全的 cookie 包gorilla/securecookie
。本文先介绍gorilla/mux
(下文简称mux
),后续文章会依次介绍上面列举的 gorilla 包。
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
我现在身边有几本 Go 语言的经典著作:
下面我们编写一个管理图书信息的 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}
使用了变量,在{}
中间指定变量名,它可以匹配路径中的特定部分。在处理