Description
I have an api group, and I want it to have a different 404 handler than the main group. I want to do something like this:
r.Group("/a").NoRoute(func(ctx *gin.Context) {
// manage no route for /a
})
r.Group("/b").NoRoute(func(ctx *gin.Context) {
// manage no route for /b
})
But it is not possible with current RouterGroup
I don't want use workaround explained here #2999, since I want to compose handler func with ctx.Next()
, ctx.Abort()
and other complex things.
Comment From: JimChenWYU
Base on the current structure of gin, I dont think gin
can solve your problem.
Just group by prefix
All routes will be registered to engine.Handlers
So only provides the global
404
handler
Comment From: jerome-laforge
Thanks for this confirmation @JimChenWYU
Comment From: jerome-laforge
I won't use gin.NoRoute(), instead of I will use this workaround:
func noRoute(r *gin.Engine, basePath string, hfs ...gin.HandlerFunc) {
r.Any(basePath+"/:path", hfs...)
}
...
noRoute(r, "/a", func(ctx *gin.Context) {
// manage no route for /a/*
})
noRoute(r, "/b", func(ctx *gin.Context) {
// manage no route for /b/*
})
Thx again @JimChenWYU for your support
Comment From: jerome-laforge
Another workaround that is more robust but also more weird, it is use 2 gin.Engine for each group (the global mergeEngine & the specific engineOnlyForA or engineOnlyForB)
mergeEngine := gin.New()
// manage all routes + noroutes for /a/*
{
engineOnlyForA := gin.New()
engineOnlyForA.GET("/a/bc", func(c *gin.Context) {
// do stuff for /a/bc
})
engineOnlyForA.GET("/a/de", func(c *gin.Context) {
// do stuff for /a/de
})
engineOnlyForA.NoRoute(func(c *gin.Context) {
// no route for /a/*
})
mergeEngine.Any("/a/*path", gin.WrapH(engineOnlyForA))
}
// manage all routes + noroutes for /b/*
{
engineOnlyForB := gin.New()
engineOnlyForB.GET("/b/cd", func(c *gin.Context) {
// do stuff for /b/cd
})
engineOnlyForB.GET("/b/ef", func(c *gin.Context) {
// do stuff for /b/ef
})
engineOnlyForB.NoRoute(func(c *gin.Context) {
// no route for /b/*
})
mergeEngine.Any("/b/*path", gin.WrapH(engineOnlyForB))
}