Documentation
¶
Overview ¶
Package validator 提供统一的参数验证能力。
基于 go-playground/validator,封装为面向接口的验证门面。 支持 struct tag 验证、自定义规则和结构体验证错误格式化。 HTTP 框架相关的绑定逻辑位于 hertz/validatorh。
用法:
type CreateUserReq struct {
Name string `json:"name" validate:"required,min=1,max=100"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"gte=0,lte=150"`
}
// 直接验证结构体
err := validator.Validate(&req)
Index ¶
- Variables
- func IsValidationError(err error) bool
- func RegisterTranslation(locale, tag, msg string) error
- func RegisterValidation(tag string, fn Func) error
- func SetDefault(v Validator)
- func Validate(obj any) error
- func ValidateVar(field any, tag string) error
- func ValidateVarNamed(field any, fieldName string, tag string) error
- type FieldError
- type Func
- type PlaygroundValidator
- func (pv *PlaygroundValidator) RegisterTranslation(locale, tag, msg string) error
- func (pv *PlaygroundValidator) RegisterValidation(tag string, fn Func) (err error)
- func (pv *PlaygroundValidator) Validate(obj any) (err error)
- func (pv *PlaygroundValidator) ValidateVar(field any, tag string) error
- func (pv *PlaygroundValidator) ValidateVarNamed(field any, fieldName string, tag string) error
- func (pv *PlaygroundValidator) Validate_() *validator.Validate
- type ValidationError
- type Validator
- type VarValidatorWithName
Constants ¶
This section is empty.
Variables ¶
var ErrNilValidationFunc = errors.New("validator: validation func must not be nil")
ErrNilValidationFunc 表示注册自定义验证规则时传入了 nil 函数(#94)。 注册期显式拦下而非推迟到校验期才炸出 nil 指针 panic——上游 go-playground/validator 的 fn==nil 守卫会被门面的包装闭包绕过 (闭包本身永不为 nil),门面必须自己再挡一道。
var ErrTranslationNotSupported = errors.New("validator: translation not supported; messages are built-in via formatMessage")
ErrTranslationNotSupported 表示当前验证器不支持错误消息翻译。 PlaygroundValidator 的错误消息已通过 formatMessage 内置英文提示, 如需自定义消息请扩展 formatMessage 或实现自定义 Validator。
Functions ¶
func IsValidationError ¶
IsValidationError 检查错误是否为 ValidationError 类型。
func RegisterTranslation ¶
RegisterTranslation 注册验证错误的翻译。
func RegisterValidation ¶
RegisterValidation 注册自定义验证规则。 ⚠️ 必须在 init 阶段(任何 Struct 校验开始前)调用:底层 go-playground/validator 的注册写内部 map 与校验读并发不安全, 运行期(流量中)注册会构成数据竞争。
func SetDefault ¶
func SetDefault(v Validator)
SetDefault 设置全局默认验证器。
v 为 nil 时**直接 panic**:存进去之后,Default() 会返回 nil 接口, 后续每一次 Default().Validate(obj) 都是空指针崩溃——崩在调用方、栈里只看 得到「validator.Default().Validate」这一行,完全看不出是这里存了个 nil。 快速失败比静默埋雷好。
func ValidateVar ¶
ValidateVar 验证单个变量。
底层校验器在单变量路径上给不出字段名 ⇒ 错误消息里的主语是兜底的 "value"。需要真实字段名(逐字段校验请求参数时)请用 ValidateVarNamed。
Types ¶
type FieldError ¶
type FieldError struct {
Field string `json:"field"` // 字段名
Tag string `json:"tag"` // 验证标签
Param string `json:"param,omitempty"` // 标签参数
Message string `json:"message"` // 错误消息
}
FieldError 表示单个字段的验证错误。
type PlaygroundValidator ¶
type PlaygroundValidator struct {
// contains filtered or unexported fields
}
PlaygroundValidator 是基于 go-playground/validator 的验证器实现。
func (*PlaygroundValidator) RegisterTranslation ¶
func (pv *PlaygroundValidator) RegisterTranslation(locale, tag, msg string) error
RegisterTranslation 注册验证错误的翻译。
当前实现不支持翻译引擎:错误消息已通过 formatMessage English prompts via formatMessage。 调用将始终返回 ErrTranslationNotSupported,避免调用方误以为翻译已注册成功。 如需自定义消息,请扩展 formatMessage 或实现自定义 Validator。
func (*PlaygroundValidator) RegisterValidation ¶
func (pv *PlaygroundValidator) RegisterValidation(tag string, fn Func) (err error)
RegisterValidation 注册自定义验证规则。
门面补三道闸(#94):
- fn == nil 注册期显式拦下(ErrNilValidationFunc):门面把 fn 包进永不为 nil 的闭包再传上游,上游的 fn==nil 守卫全部失效——此前 nil 规则注册期 报告成功、第一次用到该 tag 的线上流量才 nil 指针崩溃;
- 上游对受限 tag(required 等保留名或含受限字符)直接 panic,与「返回 error」的签名契约相反——包一层 recover 转成 error,一个拼写错误的保留 tag 不再打死进程;
- 规则自身 panic 在校验期就地隔离(invokeRule):转为「该规则校验失败」 (false ⇒ 走 ValidationError 400 路径)并记 ERROR 日志带 stack,与 registry/nacosimpl 订阅回调、registry/nacos 配置回调对「消费方回调质量 不可控」的隔离口径一致。
⚠️ 与包级 RegisterValidation 相同:必须在 init 阶段(任何 Struct 校验开始前) 调用——底层注册写内部 map 与校验读并发不安全。
func (*PlaygroundValidator) Validate ¶
func (pv *PlaygroundValidator) Validate(obj any) (err error)
Validate 验证结构体。
门面闸(#115):上游内置校验器对「tag 与字段 Kind 不匹配」的非法组合在校验期 直接 panic(如 bool/struct 字段挂 min/max/len,探针实证 "Bad field type bool")——#94 的三道闸(nil fn 注册拦截、注册期 panic 转 error、自定义规则 invokeRule 隔离)一条都不覆盖这条路径。就地 recover 转 error + ERROR 日志 (带 stack),兑现 Validator 接口「返回 error、panic 不出网」的契约;tag 误用 是服务端结构体定义 bug,按普通 error 上抛(handler 层归 500),不走 ValidationError 400——把服务端 bug 归成客户端 400 会让排障指错方向(与 RegisterValidation 注册期 panic 转 error 同口径)。
func (*PlaygroundValidator) ValidateVar ¶
func (pv *PlaygroundValidator) ValidateVar(field any, tag string) error
ValidateVar 验证单个变量。
**没有字段名可用**:底层 go-playground/validator 的 Var 路径不提供字段名 (fe.Field() 为空串)⇒ 此前错误消息是 " is required"(前导空格、没有主语), ValidationError.Map() 还会多出一个空字符串键 ""。这里用 "value" 作兜底主语; 需要真实字段名请用 ValidateVarNamed。
func (*PlaygroundValidator) ValidateVarNamed ¶ added in v0.3.3
func (pv *PlaygroundValidator) ValidateVarNamed(field any, fieldName string, tag string) error
ValidateVarNamed 验证单个变量并带上字段名。
错误消息的主语与 ValidationError.Map() 的键都用 fieldName—— 单变量校验最常见的用法(逐字段校验请求参数)需要知道是**哪个**字段没过。
func (*PlaygroundValidator) Validate_ ¶
func (pv *PlaygroundValidator) Validate_() *validator.Validate
Validate_ 返回底层验证器实例,供高级用户直接使用。
type ValidationError ¶
type ValidationError struct {
// contains filtered or unexported fields
}
ValidationError 包含多个字段验证错误。 实现 BizError 接口(code=400),handler 层的 Fail 会自动识别为 400 Bad Request。
func AsValidationError ¶
func AsValidationError(err error) (*ValidationError, bool)
AsValidationError 从错误链中提取 ValidationError(支持 errors.As 链式匹配)。
func NewFieldValidationError ¶
func NewFieldValidationError(fieldErrs []FieldError) *ValidationError
NewFieldValidationError 创建包含指定字段错误的验证错误(构造期拷贝入参, #116)。供 handler/validatorh 等外部包构造 ValidationError。入参与内部存储 不共享底层数组(slices.Clone)——调用方构造后复用底层数组做日志增强/翻译 不得让已返回给调用方的错误值内容事后漂移(构造与 Errors() 读取双向别名在 此切断,core#80 同构)。
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error 实现 error 接口,返回第一个错误消息。
func (*ValidationError) Errors ¶
func (e *ValidationError) Errors() []FieldError
Errors 返回所有字段错误(副本,#116):返回值与内部存储不共享底层数组—— 调用方排序/改写返回值不得影响错误值自身的 Error()/Map()/String()。错误值在 Go 里按惯例不可变(core#80 同款快照纪律:已发布的快照不可被事后改写)。
func (*ValidationError) Map ¶
func (e *ValidationError) Map() map[string]string
Map 返回 field→message 映射,适用于 JSON 响应。
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() error
Unwrap 返回底层的 BizError(BizCode=400, HTTPCode=400),使 errors.As 能识别为 BizError。 这样 handler 层的 Fail 会自动返回 400 Bad Request,而非 500。
type Validator ¶
type Validator interface {
// Validate 验证结构体(基于 struct tag)。
//
// 契约:panic 不出网(#115)——上游引擎对「tag 与字段 Kind 不匹配」等非法
// 组合的 panic 由门面就地转 error,实现方不得把 panic 透传给调用方。
Validate(obj any) error
// ValidateVar 验证单个变量。
//
// 契约:panic 不出网(#115),同 Validate。
ValidateVar(field any, tag string) error
// RegisterValidation 注册自定义验证规则。
//
// fn 为 nil 时返回 ErrNilValidationFunc(#94);受限 tag(上游保留名/受限
// 字符)转为 error 返回而非 panic;规则自身 panic 在校验期就地隔离为
// 「该规则校验失败」+ ERROR 日志。
RegisterValidation(tag string, fn Func) error
// RegisterTranslation 注册验证错误的翻译。
RegisterTranslation(locale, tag, msg string) error
}
Validator 是参数验证接口。
type VarValidatorWithName ¶ added in v0.3.3
type VarValidatorWithName interface {
// ValidateVarNamed 验证单个变量,错误消息与结构化错误里带上 fieldName。
ValidateVarNamed(field any, fieldName string, tag string) error
}
VarValidatorWithName 是支持「带字段名」的单变量验证器(**可选接口**)。
放在包级而不塞进 Validator 接口:给 Validator 加方法是破坏性变更 (仓外自定义实现会被迫改),而这是加法——实现方实现了它, ValidateVarNamed 就用它;没实现就退回 ValidateVar(字段名退化为 "value")。