分组路由

GoFrame框架支持分组路由的注册方式,可以给分组路由指定一个prefix前缀(也可以直接给定/前缀,表示注册在根路由下),在该分组下的所有路由注册都将注册在该路由前缀下。分组路由注册方式也是推荐的路由注册方式。

接口文档

https://pkg.go.dev/github.com/gogf/gf/v2/net/ghttp#RouterGroup

  1. // 创建分组路由
  2. func (s *Server) Group(prefix string, groups ...func(g *RouterGroup)) *RouterGroup
  3. func (d *Domain) Group(prefix string, groups ...func(g *RouterGroup)) *RouterGroup
  4. // 注册Method路由
  5. func (g *RouterGroup) ALL(pattern string, object interface{}, params...interface{})
  6. func (g *RouterGroup) GET(pattern string, object interface{}, params...interface{})
  7. func (g *RouterGroup) PUT(pattern string, object interface{}, params...interface{})
  8. func (g *RouterGroup) POST(pattern string, object interface{}, params...interface{})
  9. func (g *RouterGroup) DELETE(pattern string, object interface{}, params...interface{})
  10. func (g *RouterGroup) PATCH(pattern string, object interface{}, params...interface{})
  11. func (g *RouterGroup) HEAD(pattern string, object interface{}, params...interface{})
  12. func (g *RouterGroup) CONNECT(pattern string, object interface{}, params...interface{})
  13. func (g *RouterGroup) OPTIONS(pattern string, object interface{}, params...interface{})
  14. func (g *RouterGroup) TRACE(pattern string, object interface{}, params...interface{})
  15. // 中间件绑定
  16. func (g *RouterGroup) Middleware(handlers ...HandlerFunc) *RouterGroup
  17. // REST路由
  18. func (g *RouterGroup) REST(pattern string, object interface{})
  19. // 批量注册
  20. func (g *RouterGroup) Map(m map[string]interface{})
  21. func (g *RouterGroup) ALLMap(m map[string]interface{})
  22. // 规范化路由方式,自动绑定Handler或者路由对象
  23. func (g *RouterGroup) Bind(handlerOrObject ...interface{}) *RouterGroup

简要介绍:

  1. Group方法用于创建一个分组路由对象,并且支持在指定域名对象上创建。
  2. HTTP Method命名的方法用于绑定指定的HTTP Method路由;其中ALL方法用于注册所有的HTTP Method到指定的函数/对象/控制器上;REST方法用于注册RESTful风格的路由,需给定一个执行对象或者控制器对象。
  3. Middleware方法用于绑定一个或多个中间件到当前分组的路由上,具体详见中间件章节。

我们来看一个简单的示例:

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/net/ghttp"
  5. )
  6. func main() {
  7. s := g.Server()
  8. group := s.Group("/api")
  9. group.ALL("/all", func(r *ghttp.Request) {
  10. r.Response.Write("all")
  11. })
  12. group.GET("/get", func(r *ghttp.Request) {
  13. r.Response.Write("get")
  14. })
  15. group.POST("/post", func(r *ghttp.Request) {
  16. r.Response.Write("post")
  17. })
  18. s.SetPort(8199)
  19. s.Run()
  20. }

执行后,终端打印出路由表如下:

  1. SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
  2. |---------|---------|---------|--------|-----------|-----------------|------------|
  3. default | default | :8199 | ALL | /api/all | main.main.func1 |
  4. |---------|---------|---------|--------|-----------|-----------------|------------|
  5. default | default | :8199 | GET | /api/get | main.main.func2 |
  6. |---------|---------|---------|--------|-----------|-----------------|------------|
  7. default | default | :8199 | POST | /api/post | main.main.func3 |
  8. |---------|---------|---------|--------|-----------|-----------------|------------|

其中,/api/get仅允许GET方式访问,/api/post仅允许POST方式访问,/api/all允许所有的方式访问。

我们使用curl工具来测试一下:

  1. /api/get

    1. $ curl http://127.0.0.1:8199/api/get
    2. get
    3. $ curl -X POST http://127.0.0.1:8199/api/get
    4. Not Found
  2. `/api/post`

    1. $ curl http://127.0.0.1:8199/api/post
    2. Not Found
    3. $ curl -X POST http://127.0.0.1:8199/api/post post
  3. /api/all

    1. $ curl http://127.0.0.1:8199/api/all
    2. all
    3. $ curl -X POST http://127.0.0.1:8199/api/all
    4. all
    5. $ curl -X DELETE http://127.0.0.1:8199/api/all
    6. all
    7. $ curl -X OPTIONS http://127.0.0.1:8199/api/all
    8. all

层级注册

GoFrame框架的层级路由注册方式灵感来源于PHP Laravel框架。(眨眼)

推荐使用路由层级注册方式,注册的路由代码更清晰直观。

GoFrame框架的分组路由注册支持更加直观优雅层级的注册方式,以便于开发者更方便地管理路由列表。路由层级注册方式也是推荐的路由注册方式。

我们来看一个比较完整的示例,该示例中注册了使用到了中间件、HOOK以及不同HTTP Method绑定的路由注册:

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/net/ghttp"
  6. "github.com/gogf/gf/v2/util/gconv"
  7. "fmt"
  8. )
  9. func MiddlewareAuth(r *ghttp.Request) {
  10. token := r.Get("token")
  11. if gconv.String(token) == "123456" {
  12. r.Middleware.Next()
  13. } else {
  14. r.Response.WriteStatus(http.StatusForbidden)
  15. }
  16. }
  17. func MiddlewareCORS(r *ghttp.Request) {
  18. r.Response.CORSDefault()
  19. r.Middleware.Next()
  20. }
  21. func MiddlewareLog(r *ghttp.Request) {
  22. r.Middleware.Next()
  23. fmt.Println(r.Response.Status, r.URL.Path)
  24. }
  25. func main() {
  26. s := g.Server()
  27. s.Use(MiddlewareLog)
  28. s.Group("/api.v2", func(group *ghttp.RouterGroup) {
  29. group.Middleware(MiddlewareAuth, MiddlewareCORS)
  30. group.GET("/test", func(r *ghttp.Request) {
  31. r.Response.Write("test")
  32. })
  33. group.Group("/order", func(group *ghttp.RouterGroup) {
  34. group.GET("/list", func(r *ghttp.Request) {
  35. r.Response.Write("list")
  36. })
  37. group.PUT("/update", func(r *ghttp.Request) {
  38. r.Response.Write("update")
  39. })
  40. })
  41. group.Group("/user", func(group *ghttp.RouterGroup) {
  42. group.GET("/info", func(r *ghttp.Request) {
  43. r.Response.Write("info")
  44. })
  45. group.POST("/edit", func(r *ghttp.Request) {
  46. r.Response.Write("edit")
  47. })
  48. group.DELETE("/drop", func(r *ghttp.Request) {
  49. r.Response.Write("drop")
  50. })
  51. })
  52. group.Group("/hook", func(group *ghttp.RouterGroup) {
  53. group.Hook("/*", ghttp.HookBeforeServe, func(r *ghttp.Request) {
  54. r.Response.Write("hook any")
  55. })
  56. group.Hook("/:name", ghttp.HookBeforeServe, func(r *ghttp.Request) {
  57. r.Response.Write("hook name")
  58. })
  59. })
  60. })
  61. s.SetPort(8199)
  62. s.Run()
  63. }

执行后,注册的路由列表如下:

  1. SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
  2. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  3. default | default | :8199 | ALL | /* | main.MiddlewareLog | GLOBAL MIDDLEWARE
  4. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  5. default | default | :8199 | ALL | /api.v2/hook/* | main.main.func1.4.1 | HOOK_BEFORE_SERVE
  6. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  7. default | default | :8199 | ALL | /api.v2/hook/:name | main.main.func1.4.2 | HOOK_BEFORE_SERVE
  8. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  9. default | default | :8199 | GET | /api.v2/order/list | main.main.func1.2.1 | main.MiddlewareAuth,main.MiddlewareCORS
  10. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  11. default | default | :8199 | PUT | /api.v2/order/update | main.main.func1.2.2 | main.MiddlewareAuth,main.MiddlewareCORS
  12. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  13. default | default | :8199 | GET | /api.v2/test | main.main.func1.1 | main.MiddlewareAuth,main.MiddlewareCORS
  14. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  15. default | default | :8199 | DELETE | /api.v2/user/drop | main.main.func1.3.3 | main.MiddlewareAuth,main.MiddlewareCORS
  16. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  17. default | default | :8199 | POST | /api.v2/user/edit | main.main.func1.3.2 | main.MiddlewareAuth,main.MiddlewareCORS
  18. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
  19. default | default | :8199 | GET | /api.v2/user/info | main.main.func1.3.1 | main.MiddlewareAuth,main.MiddlewareCORS
  20. |---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|

批量注册

可以使用ALLMap方法实现批量的路由注册,例如:

  1. s := g.Server()
  2. // 前台系统路由注册
  3. s.Group("/", func(group *ghttp.RouterGroup) {
  4. group.Middleware(service.Middleware.Ctx)
  5. group.ALLMap(g.Map{
  6. "/": api.Index, // 首页
  7. "/login": api.Login, // 登录
  8. "/register": api.Register, // 注册
  9. "/category": api.Category, // 栏目
  10. "/topic": api.Topic, // 主题
  11. "/topic/:id": api.Topic.Detail, // 主题 - 详情
  12. "/ask": api.Ask, // 问答
  13. "/ask/:id": api.Ask.Detail, // 问答 - 详情
  14. "/article": api.Article, // 文章
  15. "/article/:id": api.Article.Detail, // 文章 - 详情
  16. "/reply": api.Reply, // 回复
  17. "/search": api.Search, // 搜索
  18. "/captcha": api.Captcha, // 验证码
  19. "/user/:id": api.User.Index, // 用户 - 主页
  20. })
  21. // 权限控制路由
  22. group.Group("/", func(group *ghttp.RouterGroup) {
  23. group.Middleware(service.Middleware.Auth)
  24. group.ALLMap(g.Map{
  25. "/user": api.User, // 用户
  26. "/content": api.Content, // 内容
  27. "/interact": api.Interact, // 交互
  28. "/file": api.File, // 文件
  29. })
  30. })
  31. })