在本示例,我们尝试通过数据结构化的方式,解决上一章节的参数名称硬编码问题。
请求对象
我们定义一个请求的数据结构来接收客户端提交的参数信息:
type HelloReq struct {
Name string // 名称
Age int // 年龄
}
太棒了,看起来我们既可以对参数进行注释描述,也能确定参数的类型,不再需要参数名称硬编码。
示例代码
我们调整我们前面的Web Server
程序如下:
main.go
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type HelloReq struct {
Name string // 名称
Age int // 年龄
}
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
var req HelloReq
if err := r.Parse(&req); err != nil {
r.Response.Write(err.Error())
return
}
if req.Name == "" {
r.Response.Write("name should not be empty")
return
}
if req.Age <= 0 {
r.Response.Write("invalid age value")
return
}
r.Response.Writef(
"Hello %s! Your Age is %d",
req.Name,
req.Age,
)
})
s.SetPort(8000)
s.Run()
}
在本示例中:
- 我们通过
r.Parse
方法将请求参数映射到请求对象上,随后可以通过对象的方式来使用参数。r.Parse
方法支持自动解析客户端提交参数,并赋值到指定对象上。 内部有固定的名称映射逻辑,您将在开发手册的类型转换组件中详细了解到,这里不作过多介绍。 - 同时,我们在本示例中增加了校验逻辑,
Name
及Age
参数不能为空。
执行结果
运行后,我们访问 http://127.0.0.1:8000/?name=john&age=18 可以看到,页面输出结果符合预期。
我们尝试一下错误的参数请求 http://127.0.0.1:8000/ 可以看到,参数被按照预期校验,页面输出结果同样符合预期
学习总结
在本章节中,我们学会了通过结构化请求对象的方式来规避参数名称硬编码的问题, 也能很好地维护参数的名称、描述和类型定义。
但在该示例代码中,同样有值得改进的地方:
- 其中的
r.Parse
是属于业务无关的操作,理应当独立于业务逻辑之外处理。 - 如果接口比较多的情况下,所有的接口中都要重复进行
r.Parse
操作,比较繁琐。 - 关于数据校验,如果接口的参数比较多,进行大量的
if
数据校验操作太过于繁琐。
是否有更好的方式来简化并解决这些问题呢?答案是肯定的,我们下一个章节尝试解决这一问题。