★ binding 标签体系与 validator/v10 关系
结论先行
Gin 不自己写校验器:默认的 binding 引擎就是 github.com/go-playground/validator/v10,Gin 把它的默认 tag 名从 validate 改成了 binding。所以 binding:"required"、binding:"email" 就是 validator/v10 的规则,只是换了名字。
两类标签分工
| 标签 | 作用 | 示例 |
|---|---|---|
| 编码标签 | 决定字段从哪个来源、以什么名字解析 | json、form、uri、xml |
| 校验标签(binding) | 决定绑定成功后的校验规则 | binding:"required,email" |
注意:binding 标签只在经过 binding 引擎(ShouldBind/MustBind 系列)时才生效,直接手动读 body 不会触发校验。
常用规则速查(validator/v10 语法)
- 存在性:
required(零值视为缺失:空串、0、false、nil);omitempty允许空值跳过其余规则。 - 数值/长度:
gte=1,lte=10、min=6,max=64(字符串长度)、len=11。 - 格式:
email、url、datetime=2006-01-02、uuid、hexadecimal。 - 枚举/互斥:
oneof=admin user、结构体级required_with/excluded_with系列(走binding内嵌套表达式)。 - 嵌套:结构体/切片字段自动递归,配合
dive校验元素。
自定义校验器
import "github.com/go-playground/validator/v10"
type Req struct {
Code string `json:"code" binding:"required,mycode"`
}
func init() {
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
_ = v.RegisterValidation("mycode", func(fl validator.FieldLevel) bool {
return strings.HasPrefix(fl.Field().String(), "OK-")
})
}
}
错误信息处理
- 校验失败返回的是
validator.ValidationErrors(实现了 error),可遍历取 Field/Tag/Param 拼提示。 - Gin 不提供默认中文翻译;要做友好提示需自己映射或引入 validator 官方 translator(可选方案,无内置依赖)。
- 绑定错误与校验错误都从 ShouldBind* 的返回值拿到,区分用 errors.As 断言类型。
常见追问 / 记忆点
- 追问:
binding和validatetag 有什么区别?答:没有本质区别,gin 把 validator 的 tag 名映射为 binding;若替换自定义 validator 引擎,tag 名可随之变化。 - 追问:required 对 0/false/空串有效吗?答:有效——validator 的 required 认为这些“零值”等于未提供。
- 记忆点:binding 是入口,validator/v10 是引擎;校验错误类型是 ValidationErrors,可遍历、可自定义注册规则。