如何在使用 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"