golang之路由库gorilla/mux

发布时间 2023-08-07 08:43:37作者: X-Wolf

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/