Gorilla mux 可选查询值

Posted

技术标签:

【中文标题】Gorilla mux 可选查询值【英文标题】:Gorilla mux optional query values 【发布时间】:2018-01-04 19:44:54 【问题描述】:

我一直在做一个使用 gorilla/mux 作为路由器的 Go 项目。

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

为了完成,我尝试使用接受键/值对的r.Queries 方法: 路由器。

  Path("/articles/id:[0-9]+").Queries("key", "[0-9]*?")

但这使得只有值 (456) 是可选的,而不是 key。 所以/articles/123?key=456/articles/123?key= 都有效,但/articles/123 无效。

编辑:另一个要求是,在注册路线之后,我想以编程方式构建它们,我似乎无法弄清楚如何使用r.Queries,即使文档明确指出这是可能的(@ 987654321@).

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

【问题讨论】:

一种方法:***.com/questions/43379942/… @smarx 我已经看到了这个问题,但它对我不起作用有两个原因:1. 它阻止我在处理程序 2 中使用 mux.Vars(req)["tab"]。它没有允许我按名称构建注册 URL(我已经更新了问题) 【参考方案1】:

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

urlParams := request.URL.Query()

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

【讨论】:

【参考方案2】:

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

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

router.Path("/articles/id:[0-9]+").HandlerFunc(YourHandler)

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

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

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()))

【讨论】:

我尝试过这样做,并且成功了,尽管我不知道这是否是黑客行为。唯一的问题是我想使用注册的 URL 按名称反向构建 URL 并使用它们处理查询值,但它似乎不起作用。我会更新问题。 @stassinari 我认为我最近的编辑应该可以解决您的问题。 谢谢@jmaloney,我能够让它工作。但是有一个问题:您使用r.FormValue 而不是mux.Vars 有什么原因吗?我似乎能够让它工作 另外,为了能够使用和不使用参数来构建 URL,我对路由使用了两个不同的名称,就像你的方法一样,一个名称丢失了,并且用两个“重载”了路由相同的名称与多路复用器混淆,似乎不起作用。 @stassinari 我使用r.FormValue,因为如果找不到密钥,它将返回一个空字符串,如果请求转到第二个处理程序,则使用mux.Vars 将找不到mux.Vars,处理这种情况还使您必须检查地图是否具有该值。我只使用查询参数“命名”了路由,因为使用空白查询构建 url 仍然有效并且导致代码和逻辑更少。例如,在上面的代码中,如果用户点击第二条路线,输出将只是/articles/10?key=,这很好。【参考方案3】:

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

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

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

【讨论】:

这才是真正的答案。

以上是关于Gorilla mux 可选查询值的主要内容,如果未能解决你的问题,请参考以下文章

Option可选值可选值

我应该如何用 gorilla/mux 解决这个导入问题?

gorilla/mux 的学习

GolangWeb 入门 08 集成 Gorilla Mux

GolangWeb 入门 08 集成 Gorilla Mux

如何组织 gorilla mux 路线?