Go Gorilla Mux
最后修改时间 2024 年 4 月 11 日
在本文中,我们将介绍如何在 Golang 中使用 Gorilla Mux 进行请求路由和分派。
Gorilla Mux
Gorilla Mux 是一个 HTTP 请求复用器。它用于请求路由和分派。它是标准 ServeMux
的扩展;它实现了 http.Handler
接口。
Gorilla Mux 允许执行
- 基于查询、基于路径、基于域的匹配
- 反向 URL 生成
- 带有可选正则表达式的变量
- 子路由
Gorilla Mux NewRouter
使用 mux.NewRouter
函数创建一个新的路由器。
package main import ( "fmt" "log" "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.HandleFunc("/hello", func(resp http.ResponseWriter, _ *http.Request) { fmt.Fprint(resp, "Hello there!") }) log.Println("Listening...") http.ListenAndServe(":8080", r) }
该示例为 /hello
路径返回一个简短的文本消息。
r.HandleFunc("/hello", func(resp http.ResponseWriter, _ *http.Request) { fmt.Fprint(resp, "Hello there!") })
HandleFunc
使用 URL 路径的匹配器注册一个新路由。
http.ListenAndServe(":8080", r)
我们将路由器传递给 ListenAndServe
函数。
$ curl localhost:8080/hello Hello there!
Gorilla Mux 方法
Methods
函数为 HTTP 方法添加一个匹配器。它接受一个或多个要匹配的方法序列。
package main import ( "log" "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.HandleFunc("/hello", HelloHandler).Methods("HEAD") log.Println("Listening...") http.ListenAndServe(":8080", r) } func HelloHandler(resp http.ResponseWriter, _ *http.Request) { resp.WriteHeader(http.StatusOK) }
在示例中,我们为 HEAD
方法发送 http.StatusOK
。不允许其他方法。
$ curl -I localhost:8080/hello HTTP/1.1 200 OK Date: Thu, 21 Apr 2022 13:50:21 GMT
Gorilla Mux 查询参数
查询字符串是 URL 的一部分,可用于为资源请求添加一些数据。它通常是键/值对序列。它跟在路径后面,并以 ? 字符开头。
package main import ( "fmt" "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.HandleFunc("/hello", func(resp http.ResponseWriter, req *http.Request) { name := req.URL.Query().Get("name") if name == "" { name = "guest" } fmt.Fprintf(resp, "Hello %s!", name) }) log.Println("Listening ...") http.ListenAndServe(":8080", r) }
在示例中,我们通过查询字符串发送了一个姓名。
name := req.URL.Query().Get("name")
我们从请求中获取姓名值。
$ curl localhost:8080/hello?name=John%20Doe Hello John Doe!
Gorilla Mux 路径变量
值可以通过查询参数或路径参数发送到 Web 应用程序。它们使用 {name}
或 {name:pattern}
格式定义。如果未定义正则表达式模式,则匹配的变量将是直到下一个斜杠的任何内容。
路径变量使用 mux.Vars
从请求中检索。
package main import ( "fmt" "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.HandleFunc("/hello/{name}", func(resp http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) name := vars["name"] fmt.Fprintf(resp, "Hello %s!", name) }) log.Println("Listening ...") http.ListenAndServe(":8080", r) }
在示例中,我们处理 URL 路径中的一个姓名变量。
$ curl localhost:8080/hello/John%20Doe" Hello John Doe!
Gorilla Mux JSON 响应
在下面的示例中,我们发送一个 JSON 响应。
package main import ( "encoding/json" "fmt" "log" "net/http" "time" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.HandleFunc("/now", NowHandler) log.Println("Listening ...") http.ListenAndServe(":8080", r) } func NowHandler(resp http.ResponseWriter, _ *http.Request) { now := time.Now() payload := make(map[string]string) payload["now"] = now.Format(time.ANSIC) resp.Header().Set("Content-Type", "application/json") resp.WriteHeader(http.StatusOK) json.NewEncoder(resp).Encode(payload) }
应用程序确定当前日期时间,并将其作为 JSON 响应发送。
r.HandleFunc("/now", NowHandler)
/now
路径映射到 NowHandler
函数。
now := time.Now()
我们使用 time.Now
获取当前日期时间。
payload := make(map[string]string) payload["now"] = now.Format(time.ANSIC)
我们将格式化的日期时间添加到 Go 映射中。
resp.Header().Set("Content-Type", "application/json") resp.WriteHeader(http.StatusOK)
我们设置响应的适当头部。
json.NewEncoder(resp).Encode(payload)
编码后的负载被发送回客户端。
$ curl localhost:8080/now {"now":"Thu Apr 21 16:11:16 2022"}
Gorilla Mux 子路由
子路由有助于我们将处理程序组织成逻辑组。
package main import ( "fmt" "log" "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() s1 := r.PathPrefix("/path1").Subrouter() s1.HandleFunc("/", Handler1) s2 := r.PathPrefix("/path2").Subrouter() s2.HandleFunc("/", Handler2) log.Println("Listening ...") http.ListenAndServe(":8080", r) } func Handler1(resp http.ResponseWriter, _ *http.Request) { fmt.Fprint(resp, "Subroute 1") } func Handler2(resp http.ResponseWriter, _ *http.Request) { fmt.Fprint(resp, "Subroute 2") }
该示例创建了两个子路由。
$ curl localhost:8080/path1/ Subroute 1 $ curl localhost:8080/path2/ Subroute 2
Gorilla Mux 静态文件
静态文件是不会改变的文件;它们是 CSS 文件、纯 HTML 文件、JavaScript 文件和图像。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home page</title> </head> <body> <p> Home page </p> </body> </html>
这是一个没有模板指令的纯 HTML 文件。
package main import ( "log" "net/http" "time" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.PathPrefix("/app/").Handler(http.StripPrefix("/app/", http.FileServer(http.Dir("./public")))) log.Println("Listening...") srv := &http.Server{ Handler: r, Addr: "127.0.0.1:8000", WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } log.Fatal(srv.ListenAndServe()) }
在示例中,我们为 app
URL 路径从 public
子目录提供静态文件。
r.PathPrefix("/app/").Handler(http.StripPrefix("/app/", http.FileServer(http.Dir("./public"))))
http.FileServer
从 public 子目录提供静态数据。以 /app/ 开头的 URL 路径将指向此子目录。
来源
在本文中,我们介绍了如何使用 Gorilla Mux 在 Go 中进行请求路由和分派。