为了简化路由注册方式,避免一些繁琐的参数处理细节,
让开发者将精力聚焦于业务逻辑本身,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 可以看到,页面输出结果符合预期。
我们尝试一下错误的参数请求 http://127.0.0.1:8000/ 但我们发现,页面没有输出任何的结果?
这是由于参数校验失败,并未进入到我们的路由回调函数中,而是被Server
直接返回了。
学习小结
在本章节我们学会了规范的路由注册方式,但是还缺少对返回结果,特别是产生错误之后的统一处理控制。
那么,我们应该如何捕获校验失败错误并自定义返回数据呢?我们将在下一章节更进一步介绍。