ZetCode

Go Gorilla Mux

最后修改时间 2024 年 4 月 11 日

在本文中,我们将介绍如何在 Golang 中使用 Gorilla Mux 进行请求路由和分派。

Gorilla Mux

Gorilla Mux 是一个 HTTP 请求复用器。它用于请求路由和分派。它是标准 ServeMux 的扩展;它实现了 http.Handler 接口。

Gorilla Mux 允许执行

Gorilla Mux NewRouter

使用 mux.NewRouter 函数创建一个新的路由器。

main.go
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 方法添加一个匹配器。它接受一个或多个要匹配的方法序列。

main.go
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 的一部分,可用于为资源请求添加一些数据。它通常是键/值对序列。它跟在路径后面,并以 ? 字符开头。

main.go
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 从请求中检索。

main.go
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 响应。

main.go
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 子路由

子路由有助于我们将处理程序组织成逻辑组。

main.go
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 文件和图像。

public/index.html
<!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 文件。

main.go
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 - Github 页面

在本文中,我们介绍了如何使用 Gorilla Mux 在 Go 中进行请求路由和分派。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程