Gorilla mux可选查询值

sta*_*ari 10 go mux gorilla

我一直在研究Go项目,其中使用gorilla/mux作为路由器.

我需要能够拥有与路由关联的查询值,但这些值应该是可选的.这意味着我想要捕获两者/articles/123/articles/123?key=456在同一个处理程序中.

为了做到这一点,我尝试使用r.Queries接受键/值对的方法:路由器.

  Path("/articles/{id:[0-9]+}").Queries("key", "{[0-9]*?}")
Run Code Online (Sandbox Code Playgroud)

但这只使value(456)可选,但不是key.因此,无论/articles/123?key=456/articles/123?key=是有效的,但不是/articles/123.

编辑:另一个要求是,在注册路由后,我想以编程方式构建它们,r.Queries即使文档特别指出它是可能的,我似乎无法弄清楚如何使用(https://github.com/gorilla/mux #registered-urls).

@jmaloney回答有效,但不允许从名称构建URL.

jma*_*ney 17

我只会注册你的处理程序两次.

router.Path("/articles/{id:[0-9]+}").
    Queries("key", "{[0-9]*?}").
    HandlerFunc(YourHandler).
    Name("YourHandler")

router.Path("/articles/{id:[0-9]+}").HandlerFunc(YourHandler)
Run Code Online (Sandbox Code Playgroud)

这是一个展示的工作程序.请注意,我r.FormValue用于获取查询参数.

注意:请确保您拥有最新版本,go get -u github.com/gorilla/mux因为最近未修复查询参数的错误.

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/mux"
)

var router = mux.NewRouter()

func main() {
    router.Path("/articles/{id:[0-9]+}").Queries("key", "{key}").HandlerFunc(YourHandler).Name("YourHandler")
    router.Path("/articles/{id:[0-9]+}").HandlerFunc(YourHandler)

    if err := http.ListenAndServe(":9000", router); err != nil {
        log.Fatal(err)
    }
}

func YourHandler(w http.ResponseWriter, r *http.Request) {
    id := mux.Vars(r)["id"]
    key := r.FormValue("key")

    u, err := router.Get("YourHandler").URL("id", id, "key", key)
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    // Output:
    // /articles/10?key=[key]
    w.Write([]byte(u.String()))
}
Run Code Online (Sandbox Code Playgroud)

  • @stassinari我使用`r.FormValue`,因为如果找不到键,它将返回一个空字符串,如果请求转到第二个处理程序,则不会使用`mux.Vars`找到`key`,处理这种情况也会使您必须检查地图是否具有该值。我只用查询参数“命名”了路由,因为使用空白查询构建 url 仍然有效,并导致更少的代码和逻辑。例如,在上面的代码中,如果用户点击第二条路线,输出将只是`/articles/10?key=`,这完全没问题。 (2认同)

Pav*_*kov 12

如果您注册查询参数,则它们是必需的文档

路由中定义的所有变量都是必需的,它们的值必须符合相应的模式。

因为这些参数是可选的,你只需要检查他们的处理函数内:id, found := mux.Vars(r)["id"]。哪里found会显示查询中的参数是否存在。


Nic*_*ick 11

似乎处理可选URL 参数的最佳方法是在没有它们的情况下正常定义路由器,然后像这样解析可选参数:

urlParams := request.URL.Query()
Run Code Online (Sandbox Code Playgroud)

这将返回一个包含 URL 参数作为键/值对的映射。