validator

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2023 License: Apache-2.0 Imports: 24 Imported by: 0

README

⚡ Argus

零依赖 · 高性能 · i18n 原生支持的 Go 结构体校验器

Go Reference Go Report Card License

English · 中文


✨ 特性

  • 🚀 零第三方依赖 — 仅依赖 Go 标准库,供应链安全无忧
  • 🏷️ 87+ 内置字段规则 — required、min/max、email、IP、UUID、datetime、Luhn 校验等
  • 🔗 跨字段规则 — range(范围校验)、fieldcontains(字段包含)、requiredWithout 等
  • 🌍 i18n 原生支持 — 内置 9 种语言翻译(en/zh/zh-TW/ja/ko/fr/de/es/ru),一行代码切换,可扩展任意语言
  • 🔄 go-playground/validator 兼容 — struct tag 语法和 API 高度兼容,迁移成本极低
  • 🧩 JSON Schema 校验 — 轻量 JSON Schema 子集校验,适合 API 网关场景
  • 🔒 并发安全 — 校验器实例可复用,struct 编译结果自动缓存
  • 🛠️ 自定义规则 — 支持 RegisterValidation 注册自定义校验函数,支持 context 透传
  • 📊 数组化错误输出TranslateValidationErrors 直接输出可序列化的 JSON 错误
  • 🌐 网关工具 — IP 黑白名单(CIDR/通配符)、HTTP 状态码、Header、Content-Type、JSON Path 校验
  • 📎 格式校验 — email、IP、UUID、base64、URL、协议、WebSocket
  • 📦 泛型枚举校验器NewEnumValidator[T] 类型安全的枚举值校验
  • 🔀 标签逗号转义\, 在参数中保留逗号,| 作为替代分隔符
  • 🛑 规则执行策略 — 单字段失败即短路,其他字段不受影响

🏗️ 架构

graph TB
    subgraph "用户层 User Layer"
        APP["应用代码"]
    end

    subgraph "根包 validator"
        V["Validate 实例<br/>Struct / Var 校验"]
        CACHE["编译缓存<br/>structPlan"]
        TAGS["内置规则<br/>87+ builtinRules"]
        TRANS["错误翻译<br/>translations.go → i18n.Lookup"]
        OPTS["配置选项<br/>Option / SetLocale"]
        ERRORS["错误模型<br/>ValidationErrors"]
    end

    subgraph "rule 包"
        RPARSE["标签解析<br/>ParseTag"]
        RFIELD["字段路径<br/>FieldByPath"]
        RTIME["时间规则<br/>TimeValue / ResolveTimeExpr"]
    end

    subgraph "validate 包"
        COMPARE["比较校验<br/>CompareNumbers / Strings"]
        FORMAT["格式校验<br/>Email / IP / URL / UUID / Base64"]
        ENUM["枚举校验<br/>EnumValidator"]
        JSON["JSON 校验<br/>ValidateJSON / JSONPath"]
        NETWORK["网络校验<br/>IPSet / CIDR / 通配符"]
        CONSTANTS["消息常量<br/>constants.go"]
    end

    subgraph "i18n 包(统一翻译存储)"
        I18N["i18n 核心<br/>SetLocale / Msg / Lookup / Register"]
        I18N_EN["en.go"]
        I18N_ZH["zh.go / zh_tw.go"]
        I18N_JA["ja.go / ko.go"]
        I18N_OTHER["fr.go / de.go / es.go / ru.go"]
    end

    subgraph "schema 包"
        SCHEMA["JSON Schema<br/>ValidateJSONSchema"]
    end

    APP --> V
    V --> CACHE
    V --> TAGS
    V --> TRANS
    V --> OPTS
    V --> ERRORS
    V --> RPARSE
    V --> RFIELD
    V --> RTIME

    TAGS --> FORMAT
    TAGS --> COMPARE
    TAGS --> ENUM

    APP --> COMPARE
    APP --> FORMAT
    APP --> NETWORK
    APP --> SCHEMA

    SCHEMA --> I18N
    COMPARE --> I18N
    FORMAT --> I18N
    ENUM --> I18N
    JSON --> I18N
    NETWORK --> I18N

    OPTS --> I18N
    TRANS --> I18N

    style APP fill:#e1f5fe
    style V fill:#fff3e0
    style I18N fill:#e8f5e9
    style SCHEMA fill:#fce4ec

📦 安装

go get github.com/kamalyes/go-argus

要求 Go 1.21+

🚀 快速开始

package main

import (
    "fmt"
    "github.com/kamalyes/go-argus"
)

type User struct {
    Name  string `json:"name" validate:"required,min=2,max=50"`
    Email string `json:"email" validate:"required,email"`
    Age   int    `json:"age" validate:"gte=0,lte=150"`
}

func main() {
    v := validator.New()
    err := v.Struct(User{Name: "A", Email: "bad", Age: -1})

    // 一行切换语言
    validator.SetLocale("zh")
    messages := validator.TranslateValidationErrors(err, "zh")
    for _, msg := range messages {
        fmt.Printf("%s: %s\n", msg.Field, msg.Message)
    }
    // 注册新语言(9 种内置语言:en/zh/zh-TW/ja/ko/fr/de/es/ru)
    validator.RegisterI18nMessages("pt", map[string]string{
        "required": "{field} é obrigatório",
    })
    // name: name 不能小于 2
    // email: email 必须是有效的 Email
    // age: age 必须大于或等于 0
}

📚 文档

文档 说明
docs/tags.md 所有校验标签完整参考
docs/i18n.md 国际化使用指南
docs/examples.md 完整使用示例

🔄 从 go-playground/validator 迁移

Argus 的 struct tag 语法和核心 API 与 go-playground/validator 高度兼容:

// go-playground/validator
import "github.com/go-playground/validator/v10"
v := validator.New()

// Argus — 只需改 import 路径
import "github.com/kamalyes/go-argus"
v := validator.New()

主要差异:

特性 go-playground/validator Argus
第三方依赖 多个(如 utranslator) 零依赖
i18n 需额外安装 translator 内置 9 种语言
JSON Schema 不支持 内置
IP/CIDR/网络 不支持 内置
比较校验 不支持 内置

📄 License

MIT License

Documentation

Overview

Package validator 提供零依赖 struct tag 校验和服务网关常用校验能力

Index

Constants

View Source
const (
	OpEqual                    = validate.OpEqual
	OpNotEqual                 = validate.OpNotEqual
	OpGreaterThan              = validate.OpGreaterThan
	OpGreaterThanOrEqual       = validate.OpGreaterThanOrEqual
	OpLessThan                 = validate.OpLessThan
	OpLessThanOrEqual          = validate.OpLessThanOrEqual
	OpContains                 = validate.OpContains
	OpNotContains              = validate.OpNotContains
	OpHasPrefix                = validate.OpHasPrefix
	OpHasSuffix                = validate.OpHasSuffix
	OpRegex                    = validate.OpRegex
	OpEmpty                    = validate.OpEmpty
	OpNotEmpty                 = validate.OpNotEmpty
	OpSymbolEqual              = validate.OpSymbolEqual
	OpSymbolNotEqual           = validate.OpSymbolNotEqual
	OpSymbolGreaterThan        = validate.OpSymbolGreaterThan
	OpSymbolGreaterThanOrEqual = validate.OpSymbolGreaterThanOrEqual
	OpSymbolLessThan           = validate.OpSymbolLessThan
	OpSymbolLessThanOrEqual    = validate.OpSymbolLessThanOrEqual
)

Variables

This section is empty.

Functions

func ClearRegexCache

func ClearRegexCache()

ClearRegexCache 清空正则缓存

func ContainsChinese

func ContainsChinese(s string) bool

ContainsChinese 判断字符串是否包含中文

func DerefValue

func DerefValue(value interface{}) (interface{}, bool)

DerefValue 解开 interface 中的指针值

func EmptyToDefault

func EmptyToDefault(str string, defaultStr string) string

EmptyToDefault 在字符串为空时返回默认值

func FormatSchemaError

func FormatSchemaError(result CompareResult) string

FormatSchemaError 提取 schema 校验错误消息

func GetCompiledRegex

func GetCompiledRegex(pattern string) (*regexp.Regexp, error)

GetCompiledRegex 获取编译的正则(带缓存)

func GetLocale

func GetLocale() string

GetLocale 返回当前全局语言环境

func HasEmpty

func HasEmpty(elems []interface{}) (bool, int)

HasEmpty 判断切片中是否存在空值

func IfNullOrUndefined

func IfNullOrUndefined(str string) bool

IfNullOrUndefined 判断字符串是否为 null 或 undefined

func IsAllEmpty

func IsAllEmpty(elems []interface{}) bool

IsAllEmpty 判断切片中所有元素是否都为空

func IsAllowedField

func IsAllowedField(field string, allowedFields ...[]string) bool

IsAllowedField 判断字段是否在白名单中

func IsBase64

func IsBase64(str string) bool

IsBase64 判断字符串是否为有效 Base64

func IsCEmpty

func IsCEmpty[T comparable](v T) bool

IsCEmpty 判断可比较值是否为零值

func IsEmail

func IsEmail(email string) bool

IsEmail 判断字符串是否为有效 Email

func IsEmptyAfterDeref

func IsEmptyAfterDeref(value interface{}) (interface{}, bool)

IsEmptyAfterDeref 解引用后判断值是否为空

func IsEmptyValue

func IsEmptyValue(v reflect.Value) bool

IsEmptyValue 判断 reflect.Value 是否为空值

func IsFuncType

func IsFuncType[T any]() bool

IsFuncType 判断泛型类型是否为函数

func IsIP

func IsIP(ip string) bool

IsIP 判断字符串是否为有效 IP

func IsIPAllowed

func IsIPAllowed(ip string, cidrList []string) bool

IsIPAllowed 判断 IP 是否在允许列表中

func IsIPBlocked

func IsIPBlocked(ip string, blacklist []string) bool

IsIPBlocked 判断 IP 是否在黑名单中

func IsIPInRange

func IsIPInRange(ip, start, end net.IP) bool

IsIPInRange 判断 IPv4 地址是否落在闭区间内

func IsJSONColumnType

func IsJSONColumnType(dbType string) bool

IsJSONColumnType 判断数据库列类型是否属于 JSON 类型

func IsJSONNull

func IsJSONNull(data []byte) bool

IsJSONNull 判断 JSON 字节是否为 null

func IsNil

func IsNil(x interface{}) bool

IsNil 判断 interface 是否为 nil 或内部持有 nil

func IsNull

func IsNull(str string) bool

IsNull 判断字符串是否为 null

func IsPrivateIP

func IsPrivateIP(ip string) bool

IsPrivateIP 判断 IP 是否属于常见私有或本地地址段

func IsSafeFieldName

func IsSafeFieldName(field string) bool

IsSafeFieldName 判断字段名是否安全

func IsTimeEmpty

func IsTimeEmpty(t *time.Time) bool

IsTimeEmpty 判断时间是否为空或早于 Unix epoch

func IsTimeValid

func IsTimeValid(timeVal interface{}) bool

IsTimeValid 判断时间值是否有效

func IsUUID

func IsUUID(uuid string) bool

IsUUID 判断字符串是否为有效 UUID

func IsUndefined

func IsUndefined(str string) bool

IsUndefined 判断字符串是否为 undefined

func LookupJSONPath

func LookupJSONPath(data any, path string) (any, bool)

LookupJSONPath 按轻量路径读取 JSON 数据

func MatchIPInList

func MatchIPInList(ip string, ipList []string) bool

MatchIPInList 判断 IP 是否命中任意规则

func MatchIPPattern

func MatchIPPattern(ip, pattern string) bool

MatchIPPattern 判断 IP 是否命中单个规则

func MatchIPWithWildcard

func MatchIPWithWildcard(ip, pattern string) bool

MatchIPWithWildcard 使用星号通配符匹配 IPv4

func MatchPathInList

func MatchPathInList(path string, patterns []string) bool

MatchPathInList 判断路径是否命中任意路径前缀

func NewEnumValidator

func NewEnumValidator[T comparable](values ...T) *validate.EnumValidator[T]

NewEnumValidator 创建枚举校验器

func NormalizeFilterValue

func NormalizeFilterValue(value interface{}) interface{}

NormalizeFilterValue 归一化过滤值

func NormalizeFilterValueIfNotEmpty

func NormalizeFilterValueIfNotEmpty(value interface{}) (interface{}, bool)

NormalizeFilterValueIfNotEmpty 过滤空值后返回归一化值

func NormalizeFilterValueSlice

func NormalizeFilterValueSlice(values []interface{}) []interface{}

NormalizeFilterValueSlice 归一化过滤值切片

func RegisterI18n

func RegisterI18n(locale string, key string, template string)

RegisterI18n 注册或覆盖某个语言下的单个 i18n 消息模板

func RegisterI18nMessages

func RegisterI18nMessages(locale string, messages map[string]string)

RegisterI18nMessages 批量注册某个语言下的 i18n 消息模板

func RegisterTranslation

func RegisterTranslation(locale string, tag string, template string)

RegisterTranslation 注册或覆盖某个语言下的单个规则翻译模板

func RegisterTranslations

func RegisterTranslations(locale string, items map[string]string)

RegisterTranslations 批量注册某个语言下的规则翻译模板

func ScanJSONString

func ScanJSONString(data []byte, start int) (int, error)

ScanJSONString 扫描 JSON 字符串,返回字符串结束后一位的位置

func ScanJSONValueEnd

func ScanJSONValueEnd(data []byte, start int) (int, error)

ScanJSONValueEnd 扫描任意 JSON 值,返回值结束后一位的位置

func SetLocale

func SetLocale(locale string)

SetLocale 设置全局语言环境

func SkipJSONSpaces

func SkipJSONSpaces(data []byte, i int) int

SkipJSONSpaces 跳过 JSON 字节流中的空白字符

func UnwrapProtobufWrapper

func UnwrapProtobufWrapper(value interface{}) (interface{}, bool)

UnwrapProtobufWrapper 通过反射解开 protobuf wrapper

func ValidateJSON

func ValidateJSON(data []byte) error

ValidateJSON 校验 JSON 字节是否有效

func ValidateJSONWithData

func ValidateJSONWithData(body []byte) (any, error)

ValidateJSONWithData 校验 JSON 并返回反序列化数据

Types

type CompareOperator

type CompareOperator = validate.CompareOperator

CompareOperator 表示通用比较操作符

type CompareResult

type CompareResult = validate.CompareResult

CompareResult 表示一次比较校验结果

func CompareNumbers

func CompareNumbers[T Number](actual, expect T, op CompareOperator) CompareResult

CompareNumbers 比较两个数值

func CompareStrings

func CompareStrings(actual, expect string, op CompareOperator) CompareResult

CompareStrings 比较两个字符串

func ValidateBase64

func ValidateBase64(str string) CompareResult

ValidateBase64 校验 Base64 字符串

func ValidateContains

func ValidateContains(body []byte, substring string) CompareResult

ValidateContains 校验字节内容是否包含子串

func ValidateContentType

func ValidateContentType(headers map[string]string, expected string) CompareResult

ValidateContentType 校验 Content-Type 是否包含期望类型

func ValidateEmail

func ValidateEmail(email string) CompareResult

ValidateEmail 校验 Email 格式

func ValidateHTTP

func ValidateHTTP(urlStr string) CompareResult

ValidateHTTP 校验 HTTP/HTTPS URL

func ValidateHeader

func ValidateHeader(headers map[string]string, key, expected string, op CompareOperator) CompareResult

ValidateHeader 根据操作符比较 Header 值

func ValidateIP

func ValidateIP(ipStr string) CompareResult

ValidateIP 校验 IP 地址格式(兼容旧 API)

func ValidateIPAddress

func ValidateIPAddress(ipStr string) CompareResult

ValidateIPAddress 校验 IP 地址格式

func ValidateJSONField

func ValidateJSONField(body []byte, field string, expected any) CompareResult

ValidateJSONField 校验 JSON 顶层字段是否等于期望值

func ValidateJSONFields

func ValidateJSONFields(body []byte, rules map[string]any) []CompareResult

ValidateJSONFields 批量校验 JSON 顶层字段

func ValidateJSONPath

func ValidateJSONPath(body []byte, jsonPath string, expected any, op CompareOperator) CompareResult

ValidateJSONPath 校验 JSON 路径的值

func ValidateJSONPathExists

func ValidateJSONPathExists(body []byte, jsonPath string) CompareResult

ValidateJSONPathExists 校验 JSON 路径是否存在

func ValidateJSONSchema

func ValidateJSONSchema(data interface{}, s interface{}) CompareResult

ValidateJSONSchema 校验数据是否符合 schema

func ValidateNotContains

func ValidateNotContains(body []byte, substring string) CompareResult

ValidateNotContains 校验字节内容是否不包含子串

func ValidateProtocol

func ValidateProtocol(urlStr string, allowedProtocols ...string) CompareResult

ValidateProtocol 校验 URL 协议是否在允许列表中

func ValidateRegex

func ValidateRegex(body []byte, pattern string) CompareResult

ValidateRegex 校验字节内容是否匹配正则表达式

func ValidateStatusCode

func ValidateStatusCode(statusCode, expected int, op CompareOperator) CompareResult

ValidateStatusCode 比较 HTTP 状态码

func ValidateStatusCodeRange

func ValidateStatusCodeRange(actual, min, max int) CompareResult

ValidateStatusCodeRange 校验 HTTP 状态码是否在闭区间内

func ValidateString

func ValidateString(actual, expect string, op CompareOperator) CompareResult

ValidateString 校验字符串关系

func ValidateStructWithSchema

func ValidateStructWithSchema(structData interface{}, s interface{}) CompareResult

ValidateStructWithSchema 校验结构体或 map 是否符合 schema

func ValidateUUID

func ValidateUUID(uuidStr string) CompareResult

ValidateUUID 校验 UUID 格式

func ValidateWebSocket

func ValidateWebSocket(urlStr string) CompareResult

ValidateWebSocket 校验 WebSocket URL

type FieldError

type FieldError interface {
	Tag() string
	ActualTag() string
	Namespace() string
	StructNamespace() string
	Field() string
	StructField() string
	Value() interface{}
	Param() string
	Kind() reflect.Kind
	Type() reflect.Type
	Error() string
}

FieldError 表示单个字段校验失败详情

type FieldLevel

type FieldLevel interface {
	Top() reflect.Value
	Parent() reflect.Value
	Field() reflect.Value
	FieldName() string
	StructFieldName() string
	GetTag() string
	Param() string
}

FieldLevel 为自定义规则提供当前字段、父结构和标签参数

type Func

type Func func(fl FieldLevel) bool

Func 表示自定义字段校验函数

type FuncCtx

type FuncCtx func(ctx context.Context, fl FieldLevel) bool

FuncCtx 表示带 context 的自定义字段校验函数

type IPBase

type IPBase = validate.IPBase

IPBase 提供面向对象风格的 IP 校验入口

type IPSet

type IPSet = validate.IPSet

IPSet 表示预编译 IP 规则集合

func CompileIPSet

func CompileIPSet(patterns []string) (*IPSet, error)

CompileIPSet 将 IP 规则编译为可复用集合

func MustCompileIPSet

func MustCompileIPSet(patterns []string) *IPSet

MustCompileIPSet 编译 IP 规则,失败时 panic

type InvalidValidationError

type InvalidValidationError struct {
	Type reflect.Type
}

InvalidValidationError 表示传入校验器的参数类型不合法

func (*InvalidValidationError) Error

func (e *InvalidValidationError) Error() string

type JSONSchema

type JSONSchema = schema.JSONSchema

JSONSchema 描述 Argus 支持的 JSON Schema 子集

func QuickSchema

func QuickSchema(properties map[string]string, required ...string) JSONSchema

QuickSchema 根据字段类型快速创建对象 schema

type Number

type Number interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
		~float32 | ~float64
}

Number 表示可比较数值类型集合

type Option

type Option func(*Validate)

Option 表示校验器初始化配置项

func WithPrivateFieldValidation

func WithPrivateFieldValidation() Option

WithPrivateFieldValidation 保留私有字段校验选项,用于平滑迁移 go-playground 调用

func WithRequiredStructEnabled

func WithRequiredStructEnabled() Option

WithRequiredStructEnabled 允许 required 对非指针结构体零值生效

type SchemaBuilder

type SchemaBuilder = schema.SchemaBuilder

SchemaBuilder 提供链式构建 JSONSchema 的能力

func NewSchemaBuilder

func NewSchemaBuilder() *SchemaBuilder

NewSchemaBuilder 创建 SchemaBuilder

type TagNameFunc

type TagNameFunc func(field reflect.StructField) string

TagNameFunc 用于解析字段展示名,例如从 json tag 中取字段名

type Validate

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

Validate 是可复用且并发安全的校验器实例

func New

func New(options ...Option) *Validate

New 创建校验器实例

func (*Validate) RegisterTagNameFunc

func (v *Validate) RegisterTagNameFunc(fn TagNameFunc)

RegisterTagNameFunc 注册字段展示名解析函数

func (*Validate) RegisterValidation

func (v *Validate) RegisterValidation(tag string, fn Func, _ ...bool) error

RegisterValidation 注册自定义字段校验函数

func (*Validate) RegisterValidationCtx

func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx, _ ...bool) error

RegisterValidationCtx 注册带 context 的自定义字段校验函数

func (*Validate) SetTagName

func (v *Validate) SetTagName(name string)

SetTagName 设置校验标签名,默认使用 validate

func (*Validate) Struct

func (v *Validate) Struct(s interface{}) error

Struct 根据结构体字段上的 validate 标签执行校验

func (*Validate) StructCtx

func (v *Validate) StructCtx(ctx context.Context, s interface{}) error

StructCtx 根据结构体字段上的 validate 标签执行校验,并传递 context

func (*Validate) Var

func (v *Validate) Var(field interface{}, tag string) error

Var 按标签表达式校验单个变量

func (*Validate) VarCtx

func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) error

VarCtx 按标签表达式校验单个变量,并传递 context

type ValidationErrors

type ValidationErrors []FieldError

ValidationErrors 表示字段校验失败集合

func (ValidationErrors) Error

func (ve ValidationErrors) Error() string

func (ValidationErrors) MissingFields

func (ve ValidationErrors) MissingFields() []string

MissingFields 返回 required 系列规则中缺失的字段名,字段名优先使用 json tag

func (ValidationErrors) RequiredMessages

func (ve ValidationErrors) RequiredMessages(locale string) []ValidationMessage

RequiredMessages 只返回 required 系列规则产生的缺失字段错误

func (ValidationErrors) Translate

func (ve ValidationErrors) Translate(locale string) []ValidationMessage

Translate 将 ValidationErrors 转换为数组化的 i18n 字段错误

type ValidationMessage

type ValidationMessage struct {
	Field           string      `json:"field"`
	Namespace       string      `json:"namespace"`
	StructField     string      `json:"struct_field,omitempty"`
	StructNamespace string      `json:"struct_namespace,omitempty"`
	Tag             string      `json:"tag"`
	ActualTag       string      `json:"actual_tag"`
	Param           string      `json:"param,omitempty"`
	Value           interface{} `json:"value,omitempty"`
	Message         string      `json:"message"`
}

ValidationMessage 表示一个可直接序列化给 HTTP/gRPC 网关的字段错误

func TranslateValidationErrors

func TranslateValidationErrors(err error, locale string) []ValidationMessage

TranslateValidationErrors 将 error 转换为数组化的 i18n 字段错误

Directories

Path Synopsis
Package rule 提供 Argus 的标签规则、跨字段规则和时间表达式能力
Package rule 提供 Argus 的标签规则、跨字段规则和时间表达式能力
Package schema 提供轻量 JSON Schema 子集校验能力
Package schema 提供轻量 JSON Schema 子集校验能力
Package validate 承载从 go-toolbox/pkg/validator 迁移而来的通用校验能力
Package validate 承载从 go-toolbox/pkg/validator 迁移而来的通用校验能力

Jump to

Keyboard shortcuts

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