参数校验:gvalid 标签(required/length/email/in 等)与错误返回
引言
参数不过校验就进业务,是大多数线上事故的来源。GoFrame 的 gvalid 组件把校验声明化:结构体字段写标签、数据过一遍规则,错误自动收集返回。
概念
- 使用方式:结构体字段通过
v标签声明规则,多个规则用|分隔;也可用g.Validator()对 map/对象即时校验。 - 常用规则:
required(必填)、length:6,16(长度区间)、min-length/max-length、email、integer、in:1,2,3(枚举取值)、between:1,100等;规则全集以官方文档 gvalid 章节为准。 - 自定义消息:单条规则内用
#追加错误消息,如required#名称不能为空;多条规则可用Messages方法按顺序指定。 - 错误返回:校验错误实现了 gvalid 的错误接口,可取出首条错误或错误 Map;HTTP 场景常直接把
err.Error()返回前端。
代码示例
结构体校验(与 r.Parse 联动):
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type RegisterReq struct {
Name string `v:"required|length:2,20"` // 必填且长度 2~20
Age int `v:"between:18,60"` // 取值 18~60
Email string `v:"required|email"` // 必填且为邮箱
Role string `v:"in:admin,user"` // 只能取枚举值
Phone string `v:"phone#手机号格式不正确"` // 自定义错误消息
}
func main() {
s := g.Server()
s.Group("/user", func(group *ghttp.RouterGroup) {
group.POST("/register", func(r *ghttp.Request) {
var req RegisterReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJson(g.Map{"code": 1, "message": err.Error()})
return
}
r.Response.WriteJson(g.Map{"code": 0, "message": "注册成功"})
})
})
s.SetPort(8000)
s.Run()
}
脱离 HTTP,直接用 g.Validator() 校验任意数据:
err := g.Validator().
Rules("required|length:6,16").
Data("123456").
Messages("账号不能为空", "账号长度需为 6~16 位").
Run(ctx) // ctx 为 context.Context
对 map 数据校验并拿到错误明细:
err := g.Validator().Data(g.Map{
"name": r.Get("name").String(),
}).Rules(g.Map{
"name": "required|length:2,20",
}).Run(ctx)
注意点
- 规则名或参数写错(如
between:18少一个边界)会直接报错,上线前用用例覆盖各规则。 - 多条规则的错误消息按顺序与规则一一对应;
#方式最直观,推荐优先使用。 r.Parse的自动校验依赖v标签;不带标签的字段只做类型绑定,不做校验。- 错误返回格式与"取首条还是全量"取决于调用方式,官方 gvalid 文档对错误对象结构有完整说明。
小结
v 标签让校验从"手写 if"变成"声明规则",配合 r.Parse 与规范路由几乎零成本接入。业务里组合 required/length/email/in 等规则已能覆盖绝大多数场景。完整规则表与自定义规则扩展以官方文档 goframe.org 的 gvalid 章节为准。