GorillaMux教程展示了如何在Golang中使用GorillaMux进行请求路由和调度。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
大猩猩复用器
GorillaMux是一个HTTP请求多路复用器。它用于请求路由和调度。它是标准ServeMux
的扩展;它实现了http.Handler
接口。
GorillaMux允许做:
- 基于查询、基于路径、基于域的匹配
- 反向URL生成
- 带有可选正则表达式的变量
- 子路由
大猩猩多路复用器新路由器
使用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
使用URLpath的匹配器注册一个新路由。
http.ListenAndServe(":8080", r)
我们将路由器传递给ListenAndServe
函数。
$ curl localhost:8080/hello Hello there!
大猩猩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
GorillaMux查询参数
查询字符串是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!
GorillaMux路径变量
值可以通过查询参数或路径参数发送到网络应用程序。它们以{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!
大猩猩MUXJSON响应
在下面的示例中,我们发送一个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"}
GorillaMux子路由
子路由帮助我们将处理程序组织成逻辑组。
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
GorillaMux静态文件
静态文件是不会改变的文件;它们是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
提供公共子目录中的静态数据。以/app/开头的URL路径指向此子目录。
在本教程中,我们展示了如何使用GorillaMux进行请求路由和调度inGo。
列出所有Go教程。