Skip to main content
Version: 2.7.x(Latest)

为了简化路由注册方式,避免一些繁琐的参数处理细节, 让开发者将精力聚焦于业务逻辑本身,GoFrame框架提供了规范化的路由注册方式。 规范化的路由注册方式,我们为了见名知意,便命名为了规范路由

数据结构定义

在规范路由中,我们同样定义一个请求的数据结构来接收客户端提交的参数信息,但同时需要定义一个返回对象。 目的是为了未来返回参数扩展的需要,以及未来标准化接口文档生成的需要。

type HelloReq struct {
g.Meta `path:"/" method:"get"`
Name string `v:"required" dc:"姓名"`
Age int `v:"required" dc:"年龄"`
}
type HelloRes struct {}

简要介绍:

  • 在请求对象中,我们多了一个g.Meta对象的引用,并给定了一些结构体标签。该对象为元数据对象,用于给结构体嵌入 一些定义的标签信息。例如在本示例中:
    • path:表示注册的路由地址。
    • method:表示注册绑定的HTTP Method
  • 在属性中同样出现两个新的标签名称:
    • v:表示校验规则,为valid的缩写,用于自动校验该参数。这里使用v:"required"表示该参数为必需参数,如果客户端未传递该参数时,服务端将会校验失败。
    • dc:表示参数描述信息,为description的缩写,用于描述该参数的含义。
info

在开发手册的对应章节中,有关于全部标签信息以及校验组件的详细讲解,这里只需要了解其作用即可,不做过多介绍。

路由对象管理

为了更好地管理路由注册,特别是接口比较多的场景下,如果手动一一去配置路由与回调函数关系太过于繁琐。 我们通过对象化的形式来封装路由回调函数,通过对象化封装的方式来简化我们的路由管理。 我们定义一个路由对象如下:

type Hello struct{}

func (Hello) Say(ctx context.Context, req *HelloReq) (res *HelloRes, err error) {
r := g.RequestFromCtx(ctx)
r.Response.Writef(
"Hello %s! Your Age is %d",
req.Name,
req.Age,
)
return
}
  • 我们定义了一个Hello对象,该对象用于封装路由回调函数,其所有定义的公开方法都将被作为路由回调函数进行注册。
  • 可以看到该路由对象的Say方法的回调函数的定义方式,相比较于func(*ghttp.Request)的回调函数定义方式,更符合业务逻辑函数的定义风格。
  • 在路由回调方法Say中,我们通过g.RequestFromCtx方法从ctx获取原始的*ghttp.Request请求对象,用于自定义返回内容数据。

完整示例代码

我们调整我们前面的Web Server程序如下:

main.go
package main

import (
"context"

"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)

type HelloReq struct {
g.Meta `path:"/" method:"get"`
Name string `v:"required" dc:"姓名"`
Age int `v:"required" dc:"年龄"`
}
type HelloRes struct{}

type Hello struct{}

func (Hello) Say(ctx context.Context, req *HelloReq) (res *HelloRes, err error) {
r := g.RequestFromCtx(ctx)
r.Response.Writef(
"Hello %s! Your Age is %d",
req.Name,
req.Age,
)
return
}

func main() {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.Bind(
new(Hello),
)
})
s.SetPort(8000)
s.Run()
}

在本示例中:

  • 通过s.Group的分组路由方式定义一组路由注册,在其回调方法中注册的所有路由,都会带有其定义的分组路由前缀/
  • 通过group.Bind方法注册路由对象,该方法将会遍历路由对象的所有公开方法,读取方法的输入输出结构体定义,并对其执行路由注册。

执行结果

运行后,我们访问 http://127.0.0.1:8000/?name=john&age=18 可以看到,页面输出结果符合预期。

img.png

我们尝试一下错误的参数请求 http://127.0.0.1:8000/ 但我们发现,页面没有输出任何的结果? 这是由于参数校验失败,并未进入到我们的路由回调函数中,而是被Server直接返回了。

学习小结

在本章节我们学会了规范的路由注册方式,但是还缺少对返回结果,特别是产生错误之后的统一处理控制。

那么,我们应该如何捕获校验失败错误并自定义返回数据呢?我们将在下一章节更进一步介绍。