路由分发
# 1. 路由分发
为什么需要路由分发?
- 一个项目有非常多的模块,如果全部写在一块导致代码结构混乱,不利于后续的扩展,把所有的路由注册都写在一个SetupRouter函数中的话就会太复杂了。
# 1.1 路由拆分到不同的文件
按照大的模块,每个模块有自己独立的路由,主路由可以再main.go中进行注册。
项目结构
├── go.mod
├── go.sum
├── main.go
└── routers
├── books.go
└── users.go
1
2
3
4
5
6
2
3
4
5
6
main.go
package main
import (
"days/routers"
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
routers.LoadBooks(r)
routers.LoadUsers(r)
fmt.Println("用户路由: http://127.0.0.1:8000/user")
fmt.Println("书籍路由: http://127.0.0.1:8000/book")
r.Run(":8000")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
routers/users.go
package routers
import (
"net/http"
"github.com/gin-gonic/gin"
)
func LoadUsers(e *gin.Engine) {
e.GET("/user", UserHandler)
}
func UserHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "User Router",
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
routers/books.go
package routers
import (
"net/http"
"github.com/gin-gonic/gin"
)
func LoadBooks(e *gin.Engine) {
e.GET("/book", GetBookHandler)
}
func GetBookHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Book Router",
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
测试路由分发效果
示例:
项目结构
gin_demo
├── main.go
└── routers
├── blog.go
└── shop.go
1
2
3
4
5
2
3
4
5
main.go
func main() {
r := gin.Default()
routers.LoadBlog(r)
routers.LoadShop(r)
if err := r.Run(); err != nil {
fmt.Println("startup service failed, err:%v\n", err)
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
routers/blog.go
routers/blog.go中添加一个LoadBlog的函数,将blog相关的路由注册到指定的路由器
package routers
import (
"github.com/gin-gonic/gin"
"net/http"
)
func LoadBlog(e *gin.Engine) {
e.GET("/blog", blogHandler)
}
func blogHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Blog Router",
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
routers/shop.go
routers/shop.go中添加一个LoadShop的函数,将shop相关的路由注册到指定的路由器
package routers
import (
"github.com/gin-gonic/gin"
"net/http"
)
func LoadShop(e *gin.Engine) {
e.GET("/shop", shopHandler)
}
func shopHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Shop Router",
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1.2 路由拆分到不同的APP
有时候项目规模实在太大,那么我们就更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP。
因此我们在项目目录下单独定义一个app目录,用来存放不同业务线的代码文件,这样就很容易进行横向扩展。
项目结构
gin_demo
├── app
│ ├── blog
│ │ ├── handler.go
│ │ └── router.go
│ └── shop
│ ├── handler.go
│ └── router.go
├── main.go
└── routers
└── routers.go
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
main.go
package main
import (
"fmt"
"gin_demo/app/blog"
"gin_demo/app/shop"
"gin_demo/routers"
)
func main() {
// 加载多个APP的路由配置
routers.Include(shop.Routers, blog.Routers)
// 初始化路由
r := routers.Init()
if err := r.Run(); err != nil {
fmt.Println("startup service failed, err:%v\n", err)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
routers/routers.go
package routers
import "github.com/gin-gonic/gin"
type Option func(*gin.Engine)
var options = []Option{}
// 注册app的路由配置
func Include(opts ...Option) {
options = append(options, opts...)
}
// 初始化
func Init() *gin.Engine {
r := gin.New()
for _, opt := range options {
opt(r)
}
return r
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
app/blog
app/blog/router.go
package blog
import (
"github.com/gin-gonic/gin"
)
func Routers(e *gin.Engine) {
e.GET("/blog", blogHandler)
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
app/blog/handler.go
package blog
import (
"github.com/gin-gonic/gin"
"net/http"
)
func blogHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Blog Router",
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
app/blog
app/shop/router.go
package shop
import (
"github.com/gin-gonic/gin"
)
func Routers(e *gin.Engine) {
e.GET("/shop", shopHandler)
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
app/shop/handler.go
package shop
import (
"github.com/gin-gonic/gin"
"net/http"
)
func shopHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Shop Router",
})
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
上次更新: 2022/06/29, 00:08:43