Go网络编程-Routing (using gorilla/mux)

来自泡泡学习笔记
跳到导航 跳到搜索

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(…),而是在你的路由器上调用HandleFunc,像这样:r.HandleFunc(…)。


URL参数

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

/books/go-programming-blueprint/page/10


这个URL有两个动态片段: * 书籍标题slug(go-programming-blueprint) * 页面(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)