golang mux,路由通配符&自定义功能匹配

时间:2014-02-09 20:19:41

标签: go mux

我正在使用mux软件包,它似乎运行得很好,除了它似乎不支持复杂的路由,或者至少我不知道它是如何工作的。 我有以下几条路线:

router := mux.NewRouter()
router.HandleFunc("/{productid}/{code}", product)
router.HandleFunc("/{user}", userHome)
router.HandleFunc("/search/price", searchPage)

所以我有两个问题:

  • 如何定义/ search / price / *等通配符路由,以便/ search / price / 29923 / rage / 200 / color = red等请求可以匹配?

  • 是否可以为现有路线添加自定义条件?例如如果路线为/{productid}/{code}且函数x返回true,请使用此handlerTrue,如果它返回false使用handlerFalse

我尝试在路由中添加类似.MatcherFunc(myfunction(ip)bool)的内容,但它抱怨路由器没有这样的方法。

目前,我正在处理处理程序中的“自定义”条件。

4 个答案:

答案 0 :(得分:9)

您可以使用正则表达式。像

这样的东西
router.HandleFunc(`/search/price/{rest:[a-zA-Z0-9=\-\/]+}`, searchPage)

这样,rest只捕获所有内容,因此在您的示例中rest将为29923/rage/200/color=red。您需要在代码中解析它。

你可能想要一些像可选参数。

router.HandleFunc(`/search{price:(\/price\/[0-9]+)?}{rage:(\/rage\/[0-9]+)?}{color:(\/color=[a-z]+)?}`, searchPage)

之后,您会收到仍然需要解析的变量price = "/price/29923"rage = "/rage/200"color = "/color=red",但它更容易,您可以控制哪些参数有效。如果你跳过一些参数,它会按预期工作,例如。 /search/price/29923/color=red只会提供一个空的rage变量,但仍匹配。

我不太了解你的第二个问题。

答案 1 :(得分:0)

我不太确定你需要一条“通配符”路线:你只需要一条有多个参数的路线:

/search/price/{price}/rage/{id}/color会起作用,并指出查询字符串不需要包含在匹配器中(您可以通过request.URL.Query访问它们,而您可以通过mux.Vars访问多路复用变量。也可以使用正则表达式来缩小已接受的参数。

它还有助于区分您的用户和产品路线,可能通过在其前面添加/user/{id}/products/{id}/{code}(特别是语义)。

MatcherFunc而言,您需要确保您的函数使用与MatcherFunc(这是一种类型)相同的签名:func MatchIPAddresses(*http.Request, *RouteMatch) bool将解决它。如果您希望支持代理,可以通过r.RemoteAddrr.Header.Get("X-Forwarded-For")检查Request结构中的IP地址。我通常会检查两者是否为空("")。

即。 (粗糙;你可以稍微清理一下!)

func MatchIPAddresses(r *http.Request, rm *RouteMatch) bool {
    if r.RemoteAddr == 8.8.8.8 {
        return true
    } else if r.Header.Get("X-Forwarded-For") == 8.8.8.8 {
        return true
    }

    return false
}

答案 2 :(得分:0)

使用chi作为路由器,您可以执行以下操作:

由于正则表达式永远不会与斜杠/匹配,因此您只需与*匹配

e.g。 /search/price/29923/rage/200/color=red

router.Get(`/search/price/*`, priceHandler)

func DashboardFilesHandler(w http.ResponseWriter, r *http.Request) {
    path := myhandler.UrlParam(r, "*")
    // path will be '29923/rage/200/color=red'
}

另请参阅:https://godoc.org/github.com/go-chi/chi

  

带有名称后跟冒号的占位符允许常规   表达式匹配,例如{number:\ d +}。正则表达式   语法是Go的正常regexp RE2语法,除了常规   不支持包含{或}的表达式, /永远不会   匹配。允许使用空字符串的匿名正则表达式模式   在占位符中的冒号之前,例如{:\ d +}

     

星号的特殊占位符与所请求的其余部分匹配   网址。模式中的任何尾随字符都会被忽略。这是   只有匹配/字符的占位符。

答案 3 :(得分:0)

要对大猩猩mux使用自定义MatcherFunc,需要确保您的matcher实际上是mux.MatcherFunc类型。这是因为MatcheFunc不是接口类型

// From mux/route.go line 303
// MatcherFunc is the function signature used by custom matchers.
type MatcherFunc func(*http.Request, *RouteMatch) bool

因此,您必须执行以下操作:

var myMatcher mux.MatcherFunc = func(request *http.Request, match *mux.RouteMatch) bool {
  // Your custom logic
  return trueOrFalse
}

// You can then use it on your route like this.
router := mux.NewRouter()
router.HandleFunc("/{productid}/{code}", product).MatcherFunc(myMatcher)