How to add multiple groups to gin routing for api version inheritance?

Berti92 picture Berti92 · Feb 21, 2017 · Viewed 8k times · Source

I'm currently working on a API with Go + Gin.

The API should include a version string, for example the string v1

http://127.0.0.1:3000/v1/user/get_username

That is no problem, because I can create a group with Gin

v1 := router.Group("/v1")
v1.GET("/user/get_username", modules.UserGetUsername)

But... if I start a new API-Version "v2" and the code within the function UserGetUsername didn't changed I must do the following

v1 := router.Group("/v1")
v1.GET("/user/get_username", modules.UserGetUsername)
v2 := router.Group("/v2")
v2.GET("/user/get_username", modules.UserGetUsername)

Is there a nicer solution for that - maybe something like that:

v1_v2 := router.Group("/v1").AnotherGroup("/v2")
v1_v2.GET("/user/get_username", modules.UserGetUsername)

Thank you for your suggestions.

Answer

Zoyd picture Zoyd · Feb 21, 2017

I don’t think Gin provides this, but it looks easy to write.

type GroupGroup struct {
    groups []*gin.RouterGroup
}

func NewGroupGroup(groups []*gin.RouterGroup) GroupGroup {
    return GroupGroup {
        groups,
    }
}

func (g *GroupGroup) handle(method string, path string, handler gin.HandlerFunc) {
    for _, group := range g.groups {
        group.Handle(method, path, handler)
    }
}

Then, you can use it like so :

v1 := router.Group("/v1")
v2 := router.Group("/v2")

g := NewGroupGroup([]*gin.RouterGroup { v1, v2 })

g.handle(http.MethodGet, "hello", sayHello)
g.handle(http.MethodPost, "goodbye", sayGoodbye)