参数校验: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 能覆盖必填、边界、格式、枚举四类需求。错误默认是英文机读文本,下一章讲两件事:把错误翻译成人话、注册业务自定义规则。

笔记加载中…