路由(使用 gorilla/mux)

嗨,我是 Philipp!
我想告诉你,我的平台Go Web 示例课程刚刚推出。享受有关 Go 中 Web 开发的易于遵循的视频课程。务必查看我为早期支持者提供的特别优惠。
我们会在那里见到你! :)
了解更多

简介

Go 的 net/http 包为 HTTP 协议提供了许多功能。它做得不太好的一件事是复杂请求路由,比如将请求 URL 细分为单个参数。幸运的是,有一个非常流行的包可以做到这一点,它以 Go 社区良好的代码质量而闻名。在本示例中,你将看到如何使用 gorilla/mux 包创建带有命名参数、GET/POST 处理程序和域限制的路由。

安装 gorilla/mux

gorilla/mux 是一个适应 Go 的默认 HTTP 路由器的包。它附带了许多功能,可以提高编写 Web 应用程序时的生产力。它还符合 Go 的默认请求处理程序签名 func (w http.ResponseWriter, r *http.Request),因此该包可以与其他 HTTP 库(如中间件或现有应用程序)混合和匹配。使用 go get 命令从 GitHub 安装包,如下所示

go get -u github.com/gorilla/mux

创建新路由器

首先创建一个新的请求路由器。路由器是 Web 应用程序的主路由器,稍后将作为参数传递给服务器。它将接收所有 HTTP 连接,并将其传递给你将在其上注册的请求处理程序。你可以像这样创建一个新路由器

r := mux.NewRouter()

注册请求处理程序

一旦你有了新的路由器,你就可以像往常一样注册请求处理程序。唯一的区别是,你不再调用 http.HandleFunc(...),而是像这样在路由器上调用 HandleFuncr.HandleFunc(...)

URL 参数

gorilla/mux 路由器最大的优势是能够从请求 URL 中提取片段。例如,这是应用程序中的一个 URL

/books/go-programming-blueprint/page/10
此 URL 有两个动态片段

  1. 图书标题缩写(go-programming-blueprint)
  2. 页面(10)

要让请求处理程序与上面提到的 URL 匹配,你需要用 URL 模式中的占位符替换动态片段,如下所示

r.HandleFunc("/books/{title}/page/{page}", func(w http.ResponseWriter, r *http.Request) {
    // get the book
    // navigate to the page
})

最后一步是从这些片段中获取数据。该包附带了函数 mux.Vars(r),它将 http.Request 作为参数,并返回片段的映射。

func(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    vars["title"] // the book title slug
    vars["page"] // the page
}

设置 HTTP 服务器的路由器

您是否曾经想过 http.ListenAndServe(":80", nil) 中的 nil 意味着什么?它是 HTTP 服务器的主路由器的参数。默认情况下它是 nil,这意味着使用 net/http 包的默认路由器。要使用您自己的路由器,请用路由器 r 的变量替换 nil

http.ListenAndServe(":80", r)

代码(用于复制/粘贴)

这是您可以用来尝试在本示例中学习到的内容的完整代码。

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/books/{title}/page/{page}", func(w http.ResponseWriter, r *http.Request) {
        vars := mux.Vars(r)
        title := vars["title"]
        page := vars["page"]

        fmt.Fprintf(w, "You've requested the book: %s on page %s\n", title, page)
    })

    http.ListenAndServe(":80", r)
}

gorilla/mux 路由器的功能

方法

将请求处理程序限制为特定的 HTTP 方法。

r.HandleFunc("/books/{title}", CreateBook).Methods("POST")
r.HandleFunc("/books/{title}", ReadBook).Methods("GET")
r.HandleFunc("/books/{title}", UpdateBook).Methods("PUT")
r.HandleFunc("/books/{title}", DeleteBook).Methods("DELETE")

主机名和子域

将请求处理程序限制为特定的主机名或子域。

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

方案

将请求处理程序限制为 http/https。

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

路径前缀和子路由

将请求处理程序限制为特定的路径前缀。

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