如何在使用 router.Any 和通配符处理请求后保留路径参数
How to preserve path params after handling a request with router.Any and wildcard
在我的例子中,需要捕获请求并检查是否是内部请求。如果没有,将这些请求重定向到其他处理函数。
URL 示例:
1. URL: http://localhost/internal/dosomething1
2. URL: http://localhost/internal/dosomething2/:id
3. URL: http://localhost/overview
4. URL: http://localhost/xxx
只有以 internal
开头的 URI 应该在我自己的句柄函数中处理(情况 1 和 2)。
具有任何请求方法的其他人将代理到另一个函数(情况 3 和 4)。
我正在尝试这样使用 router.Any("/*uri", handlerExternal)
:
func handlerExternal(c *gin.Context) {
path := c.Param("uri")
if strings.HasPrefix(path, "/internal/") {
uri := strings.Split(path, "/")
switch uri[2] {
case "dosomething1":
doInternal(c)
}
} else {
doExternal(c)
}
}
但是使用此解决方案,doInternal(c)
无法像 http://localhost/internal/dosomething2/:id
那样捕获 :id
之类的路径参数
这种情况有没有更好的解决方案?
使用 sub-engine.
您可以使用 gin.New
仅针对内部路由 而不是 运行 it 实例化引擎。相反,您将上下文从 Any
路由传递到 Engine.HandleContext
.
这将中继来自主引擎的上下文,并将根据 sub-routes.
中的占位符匹配路径参数
您可以照常在 sub-engine 上声明路由:
func main() {
internalEngine := gin.New()
internalEngine.GET("/internal/dosomething1", func(c *gin.Context) { c.JSON(200, "ok") })
internalEngine.GET("/internal/dosomething2/:id", func(c *gin.Context) { c.JSON(200, c.Param("id")) })
mainEngine := gin.New()
mainEngine.Any("/*uri", func(c *gin.Context) {
path := c.Param("uri")
if strings.HasPrefix(path, "/internal/") {
uri := strings.Split(path, "/")
switch uri[2] {
case "dosomething1", "dosomething2":
internalEngine.HandleContext(c)
}
} else {
doExternal(c)
}
})
mainEngine.Run(":8800")
}
您还可以在将上下文中继到 sub-engine 之前修改 c.Request.URL.Path
,例如如果您愿意,可以删除 internal
前缀。
现在,如果您尝试向以下地址发送 GET 请求:
http://localhost:8855/internal/dosomething2/1234
它将回显输出:
"1234"
在我的例子中,需要捕获请求并检查是否是内部请求。如果没有,将这些请求重定向到其他处理函数。
URL 示例:
1. URL: http://localhost/internal/dosomething1
2. URL: http://localhost/internal/dosomething2/:id
3. URL: http://localhost/overview
4. URL: http://localhost/xxx
只有以 internal
开头的 URI 应该在我自己的句柄函数中处理(情况 1 和 2)。
具有任何请求方法的其他人将代理到另一个函数(情况 3 和 4)。
我正在尝试这样使用 router.Any("/*uri", handlerExternal)
:
func handlerExternal(c *gin.Context) {
path := c.Param("uri")
if strings.HasPrefix(path, "/internal/") {
uri := strings.Split(path, "/")
switch uri[2] {
case "dosomething1":
doInternal(c)
}
} else {
doExternal(c)
}
}
但是使用此解决方案,doInternal(c)
无法像 http://localhost/internal/dosomething2/:id
:id
之类的路径参数
这种情况有没有更好的解决方案?
使用 sub-engine.
您可以使用 gin.New
仅针对内部路由 而不是 运行 it 实例化引擎。相反,您将上下文从 Any
路由传递到 Engine.HandleContext
.
这将中继来自主引擎的上下文,并将根据 sub-routes.
中的占位符匹配路径参数您可以照常在 sub-engine 上声明路由:
func main() {
internalEngine := gin.New()
internalEngine.GET("/internal/dosomething1", func(c *gin.Context) { c.JSON(200, "ok") })
internalEngine.GET("/internal/dosomething2/:id", func(c *gin.Context) { c.JSON(200, c.Param("id")) })
mainEngine := gin.New()
mainEngine.Any("/*uri", func(c *gin.Context) {
path := c.Param("uri")
if strings.HasPrefix(path, "/internal/") {
uri := strings.Split(path, "/")
switch uri[2] {
case "dosomething1", "dosomething2":
internalEngine.HandleContext(c)
}
} else {
doExternal(c)
}
})
mainEngine.Run(":8800")
}
您还可以在将上下文中继到 sub-engine 之前修改 c.Request.URL.Path
,例如如果您愿意,可以删除 internal
前缀。
现在,如果您尝试向以下地址发送 GET 请求:
http://localhost:8855/internal/dosomething2/1234
它将回显输出:
"1234"