参数校验:binding 常用 tag 与错误处理
本章解决什么问题:第 7 章的 required 只是开始。validator v10 提供大量规则 tag,本章列出最常用的一批,并示范如何捕获、初步处理校验错误。
常用 tag 一览
- required:必填,空字符串、数字 0、false 等零值视为缺失;
- min / max:下限与上限——字符串按长度、数字按大小、数组与切片按元素个数;
- gte / lte / gt / lt:数值或时间比较,gte 表示 >=;
- len:固定长度(字符串按字符数、切片按个数);
- email:邮箱格式;
- oneof=a b c:取值必须在候选集合内;
- datetime=2006-01-02:按 Go 参考时间布局校验字符串日期;
- omitempty:字段为空时跳过其余规则,常与 email 等组合使用。
多条规则用逗号连接,如 binding:"required,min=2,max=50"。
一个组合示例
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
type Event struct {
Title string `json:"title" binding:"required,min=2,max=50"`
Email string `json:"email" binding:"omitempty,email"`
Day string `json:"day" binding:"required,datetime=2006-01-02"`
}
func main() {
r := gin.Default()
r.POST("/events", func(c *gin.Context) {
var e Event
if err := c.ShouldBindJSON(&e); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"title": e.Title, "day": e.Day})
})
r.Run(":8080")
}
绑定错误发生在两层:类型不匹配(如把 "abc" 绑给 int 字段)属于解码错误;规则不满足(如 Title 过短)属于校验错误,错误文本形如 Key: 'Event.Title' Error:Field validation for 'Title' failed on the 'min' tag。
错误处理的分层思路
- 第一版先把 err.Error() 原样返回,方便开发期排查;
- 面向用户时,把 validator.ValidationErrors 逐条转成可读消息(第 16 章);
- 规则足够复杂(跨字段、跨结构体、逐元素)时,validator v10 还有 dive、structonly、eqfield 等高级用法,具体以官方文档 gin-gonic.com 与 validator 文档为准。
关键点
- binding tag 与 validator tag 同源,多规则逗号分隔、顺序无关。
- required 判“零值”,与“字段是否出现”不是一回事,别混用。
- 校验发生在绑定成功之后;类型错误与规则错误要分开对待。
小结
常用 tag 能覆盖必填、边界、格式、枚举四类需求。错误默认是英文机读文本,下一章讲两件事:把错误翻译成人话、注册业务自定义规则。