In my case need to catch request and check is internal request or not. If not, redirect these request to other handler function.
URL example:
1. URL: http://localhost/internal/dosomething1
2. URL: http://localhost/internal/dosomething2/:id
3. URL: http://localhost/overview
4. URL: http://localhost/xxx
Only the URIs that start with internal
should be handled in my own handle function (cases 1 and 2).
Others with any request method will proxy to another function (cases 3 and 4).
I am trying to use router.Any("/*uri", handlerExternal)
as such:
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)
}
}
But with this solution, the doInternal(c)
cannot catch path parameters like :id
as in http://localhost/internal/dosomething2/:id
Is there any better solution for this case?
CodePudding user response:
Use a sub-engine.
You can instantiate an engine with gin.New
for internal routes only and not run it. Instead you pass the context from your Any
route to Engine.HandleContext
.
This will relay the context from the main engine, and it will match path params based on the placeholders in the sub-routes.
You can declare routes on the sub-engine as usual:
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")
}
You can also modify c.Request.URL.Path
before relaying the context to the sub-engine, e.g. by removing the internal
prefix, if so you wish.
Now if you try a GET request to:
http://localhost:8855/internal/dosomething2/1234
it will echo the output:
"1234"