How to combine group of routes in gin? [duplicate]
Asked Answered
P

2

8

I have created two different Groups for gin routing specifically /user and /todo in two different packages and I want to merge them into one file . Here is my userroutes.go file.

package userrouter

import (
    "github.com/gin-gonic/gin"
)

//UserRoutes for user
func UserRoutes() *gin.RouterGroup {

    r := gin.Default()

    v1 := r.Group("/user")
    {

        v1.GET("/hello", func(c *gin.Context) {
            c.JSON(200, gin.H{
                "message": "pong",
            })
        })

    }
    return v1

}

and todoroutes.go as

package todorouter

import (
    "github.com/gin-gonic/gin"
)

//TodoRoutes for creating Todo
func TodoRoutes() *gin.RouterGroup {

    r := gin.Default()

    v2 := r.Group("/todo")
    {

        v2.GET("/hello", func(c *gin.Context) {
            c.JSON(200, gin.H{
                "message": "pong",
            })
        })

    }
    return v2

}

and then want to merge them in routes.go.

package router

import (
    todo "TODO/api/Routes/Todo/TodoRoutes"
    user "TODO/api/Routes/User/UserRoutes"
    "fmt"

    "github.com/gin-gonic/gin"
)


//Router for all routes
func Router() {
    // r := gin.Default()
    userRoutes := user.UserRoutes()
    todoRoutes := todo.TodoRoutes()

}

How can I merge them into one file so that they could be fetched with some prefix /api like localhost:8081/api/user/create or localhost:8081/api/todo/create. Additionaly do I need to create r := gin.Default() in every route I've been creating or it can be accomplished using once? Thanks.

Peace answered 27/6, 2020 at 9:48 Comment(0)
D
10

Just create a super-group and then create your groups under it. Code example to show what I mean:

    router := gin.New()
    
    superGroup := router.Group("/api")
    {
        userGroup := superGroup.Group("/user")
        {
            // user group handlers
        }
    
        todoGroup := superGroup.Group("/todo")
        {
            // todo group handlers
        }
    }

With this code you can't create your groups as you are doing now, because both your functions todorouter.TodoRoutes and userrouter.UserRoutes instantiate their own gin.Engine. So you have to move the top-level engine and /api group to a common place.

If you want, you can then pass the api group object as a function argument. Example:

//TodoRoutes for creating Todo
func TodoRoutes(apiGroup *gin.RouterGroup) {

    v2 := apiGroup.Group("/todo")
    {

        v2.GET("/hello", func(c *gin.Context) {
            c.JSON(200, gin.H{
                "message": "pong",
            })
        })

    }
}

However my recommendation to keep your code well organized is to instantiate all routers in the same place, and then place the handlers in separate packages.

// package todoroutes
func HandleHello(c *gin.Context) {
            c.JSON(200, gin.H{
                "message": "pong",
            })
}

// package router
    router := gin.New()
    
    superGroup := router.Group("/api")
    {
        userGroup := superGroup.Group("/user")
        {
             userGroup.GET("/hello", todoroutes.HandleHello)
        }
    }

Desrochers answered 27/6, 2020 at 10:15 Comment(2)
Thanks for the reply . Though I've one doubt regarding last recommendation. Won't it become a little messy if I keep adding Routes in either userGroup or say todoGroup? Just a thoughtPeace
I think the key point that means you can structure the endpoints as you prefer was this part of the answer: "pass the api group object as a function argument".Buckles
F
9

This answer is based on blackgreen's answer. This is my solution to a similar problem. I created a supergroup ("/api/v1") then add the child groupes ("users", "books") under it. I was able to place the child groupes into different files and send them a single instance of gin.RouterGroup(). As the result I have this nice and clean folder structure:

controllers/
  user_controllers
  book_controllers
routes/
  user_routes
  book_routes
  index
middlewares/
  all
main.go

main.go

func startServer() {
    app := gin.New()

    router := app.Group("/api/v1")
    routes.AddRoutes(router)

    utils.ConnectDatabase()

    app.Run(":5500")
}

routes/book_routes.go

package routes

func bookRoutes(superRoute *gin.RouterGroup) {
    booksRouter := superRoute.Group("/books")
    {
        booksRouter.GET("/", controllers.BookControllers.GetBooks)

        booksRouter.POST("/", controllers.BookControllers.CreateBook)
    }
}

routes/user_routes.go

package routes

func userRoutes(superRoute *gin.RouterGroup) {
    userRouter := superRoute.Group("/users")
    {
        userRouter.GET("/", controllers.UserControllers.GetUsers)

        userRouter.POST("/", controllers.UserControllers.CreateUser)
    }
}

routes/index.go

func AddRoutes(superRoute *gin.RouterGroup) {
    bookRoutes(superRoute)
    userRoutes(superRoute)
}

Thanks stackoverflow community

Francois answered 9/4, 2022 at 0:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.