2017-07-28 84 views
4

我一直在使用gorilla/mux作为路由器的Go项目。Gorilla mux可选查询值

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

为了实现这样我尝试使用r.Queries方法接受键/值对: router. Path("/articles/{id:[0-9]+}"). Queries("key", "{[0-9]*?}") 但是这使得只有值(456)可选的,但是不是key。 因此/articles/123?key=456/articles/123?key=都是有效的,但不是/articles/123

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

@jmaloney答案的作品,但不允许从名称建立网址。

+0

一种方法:https://stackoverflow.com/questions/43379942/how-to-have-an-optional-query-in-get-request-using-gorilla-mux – smarx

+0

@smarx我见过这个问题,但有两个原因为什么它不适用于我: 1.它阻止我在我的处理程序中使用'mux.Vars(req)[“tab”]' 2.它不允许我按名称构建注册的URL(我已更新了该问题) – stassinari

回答

5

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

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())) 
} 
+0

我试图做到这一点,并开始工作,即使我不知道它是否是黑客行为。 唯一的问题是我想使用已注册的URL来按名称反向构建URL并使用它们处理查询值,但似乎不起作用。我会更新这个问题。 – stassinari

+0

@stassinari我认为我最近的编辑应该解决您的问题。 – jmaloney

+0

谢谢@ jmaloney,我能够让它工作。有一个问题:是否有一个原因,你使用'r.FormValue'而不是'mux.Vars'?我似乎能够得到它的工作 – stassinari

0

如果您注册查询参数它们需要doc

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

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