我正在使用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)
的内容,但它抱怨路由器没有这样的方法。
目前,我正在处理处理程序中的“自定义”条件。
答案 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.RemoteAddr
或r.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)