validator

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 10 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
var ErrNilValidationFunc = errors.New("validator: validation func must not be nil")

ErrNilValidationFunc 表示注册自定义验证规则时传入了 nil 函数(#94)。 注册期显式拦下而非推迟到校验期才炸出 nil 指针 panic——上游 go-playground/validator 的 fn==nil 守卫会被门面的包装闭包绕过 (闭包本身永不为 nil),门面必须自己再挡一道。

View Source
var ErrTranslationNotSupported = errors.New("validator: translation not supported; messages are built-in via formatMessage")

ErrTranslationNotSupported 表示当前验证器不支持错误消息翻译。 PlaygroundValidator 的错误消息已通过 formatMessage 内置英文提示, 如需自定义消息请扩展 formatMessage 或实现自定义 Validator。

Functions

func IsValidationError

func IsValidationError(err error) bool

IsValidationError 检查错误是否为 ValidationError 类型。

func RegisterTranslation

func RegisterTranslation(locale, tag, msg string) error

RegisterTranslation 注册验证错误的翻译。

func RegisterValidation

func RegisterValidation(tag string, fn Func) error

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 Validate

func Validate(obj any) error

Validate 验证结构体。

func ValidateVar

func ValidateVar(field any, tag string) error

ValidateVar 验证单个变量。

底层校验器在单变量路径上给不出字段名 ⇒ 错误消息里的主语是兜底的 "value"。需要真实字段名(逐字段校验请求参数时)请用 ValidateVarNamed。

func ValidateVarNamed added in v0.3.3

func ValidateVarNamed(field any, fieldName string, tag string) error

ValidateVarNamed 验证单个变量并带上字段名。

错误消息的主语与 ValidationError.Map() 的键都用 fieldName—— 单变量校验最常见的用法需要知道是**哪个**字段没过。

实现方实现了 VarValidatorWithName 时用它;否则退回 ValidateVar (字段名退化为 "value")。

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 Func

type Func func(val any) bool

Func 是自定义验证函数。

type PlaygroundValidator

type PlaygroundValidator struct {
	// contains filtered or unexported fields
}

PlaygroundValidator 是基于 go-playground/validator 的验证器实现。

func New

func New() *PlaygroundValidator

New 创建 PlaygroundValidator 实例。

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) Len

func (e *ValidationError) Len() int

Len 返回错误数量。

func (*ValidationError) Map

func (e *ValidationError) Map() map[string]string

Map 返回 field→message 映射,适用于 JSON 响应。

func (*ValidationError) String

func (e *ValidationError) String() string

String 实现 fmt.Stringer。

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 是参数验证接口。

func Default

func Default() Validator

Default 获取全局默认验证器。

兜底:atomic 指针为空时(理论上只有 init 之前才可能)返回一个可用的默认 验证器,而不是在解引用处空指针崩溃。

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")。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL