golang请求数据验证与校验插件库valix的使用

Golang请求数据验证与校验插件库Valix的使用

Valix是一个用于验证请求的Go包,特别适合验证JSON格式的HTTP请求。

安装

使用go get安装Valix:

go get github.com/marrow16/valix

更新到最新版本:

go get -u github.com/marrow16/valix

特性

  • 深度验证(支持嵌套对象和数组的验证)
  • 可以从结构体创建验证器或直接代码定义
  • 验证http.Request到结构体或map[string]interface{}
  • 发现所有验证违规而不仅仅是第一个
  • 丰富的预定义约束集合
  • 可自定义约束
  • 支持条件约束
  • 完整的多态验证支持
  • 国际化支持(i18n)
  • 验证器可序列化为JSON
  • 高度可扩展
  • 100%测试覆盖

基本概念

Valix基于API请求应该尽早验证的理念。验证JSON对象时执行以下步骤:

  1. 可选检查整个对象的约束
  2. 检查是否有未知属性(除非设置忽略)
  3. 对每个定义的属性:
    • 检查是否存在(如果设置为必需)
    • 检查是否为非null(如果设置为非null)
    • 检查值类型是否正确
    • 检查值是否符合约束
    • 如果值是对象或数组,使用指定验证器

更多关于golang请求数据验证与校验插件库valix的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang请求数据验证与校验插件库valix的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 数据验证与校验插件库 valix 使用指南

valix 是一个强大的 Go 语言数据验证库,专门用于验证 JSON 请求数据。它提供了丰富的验证规则和灵活的验证方式。

基本使用

安装

go get github.com/marrow16/valix

基本示例

package main

import (
	"encoding/json"
	"fmt"
	"github.com/marrow16/valix"
)

type Person struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Email   string `json:"email"`
	Address string `json:"address"`
}

func main() {
	// 创建验证器
	validator := &valix.Validator{
		Properties: valix.Properties{
			"name": {
				Type:      valix.String,
				NotNull:   true,
				Mandatory: true,
				Constraints: valix.Constraints{
					&valix.StringLength{Minimum: 2, Maximum: 50},
				},
			},
			"age": {
				Type:    valix.Integer,
				NotNull: true,
				Constraints: valix.Constraints{
					&valix.Minimum{Value: 0},
					&valix.Maximum{Value: 120},
				},
			},
			"email": {
				Type:      valix.String,
				NotNull:   true,
				Mandatory: true,
				Constraints: valix.Constraints{
					&valix.StringPattern{Regexp: `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`},
				},
			},
			"address": {
				Type:    valix.String,
				NotNull: false, // 可选字段
			},
		},
	}

	// 测试数据
	jsonStr := `{
		"name": "John Doe",
		"age": 30,
		"email": "john@example.com"
	}`

	var person Person
	err := json.Unmarshal([]byte(jsonStr), &person)
	if err != nil {
		fmt.Println("JSON 解析错误:", err)
		return
	}

	// 验证数据
	violations := validator.Validate(jsonStr)
	if len(violations) > 0 {
		fmt.Println("验证错误:")
		for _, v := range violations {
			fmt.Printf("- %s (路径: %s)\n", v.Message, v.Property)
		}
	} else {
		fmt.Println("验证通过!")
	}
}

高级功能

自定义验证器

// 自定义验证函数
func isAdult(value interface{}, vcx *valix.ValidatorContext, this *valix.Constraint) (bool, string) {
	if age, ok := value.(float64); ok {
		if age >= 18 {
			return true, ""
		}
		return false, "必须年满18岁"
	}
	return false, "无效的年龄值"
}

// 使用自定义验证器
validator := &valix.Validator{
	Properties: valix.Properties{
		"age": {
			Type:    valix.Integer,
			NotNull: true,
			Constraints: valix.Constraints{
				&valix.CustomConstraint{
					ValidateFn: isAdult,
				},
			},
		},
	},
}

条件验证

validator := &valix.Validator{
	Properties: valix.Properties{
		"has_discount": {
			Type:    valix.Boolean,
			NotNull: true,
		},
		"discount_code": {
			Type:    valix.String,
			NotNull: false,
			Conditions: []*valix.PropertyCondition{
				{
					When: "has_discount == true",
					Constraints: valix.Constraints{
						&valix.StringLength{Minimum: 5, Maximum: 20},
					},
					Mandatory: true,
				},
			},
		},
	},
}

嵌套结构验证

type Address struct {
	Street  string `json:"street"`
	City    string `json:"city"`
	Country string `json:"country"`
}

type User struct {
	Name    string  `json:"name"`
	Address Address `json:"address"`
}

addressValidator := &valix.Validator{
	Properties: valix.Properties{
		"street": {
			Type:      valix.String,
			NotNull:   true,
			Mandatory: true,
		},
		"city": {
			Type:      valix.String,
			NotNull:   true,
			Mandatory: true,
		},
		"country": {
			Type:      valix.String,
			NotNull:   true,
			Mandatory: true,
		},
	},
}

userValidator := &valix.Validator{
	Properties: valix.Properties{
		"name": {
			Type:      valix.String,
			NotNull:   true,
			Mandatory: true,
		},
		"address": {
			Type:        valix.Object,
			NotNull:     true,
			Mandatory:   true,
			ObjectValidator: addressValidator,
		},
	},
}

数组验证

validator := &valix.Validator{
	Properties: valix.Properties{
		"tags": {
			Type:      valix.Array,
			NotNull:   true,
			Mandatory: true,
			Constraints: valix.Constraints{
				&valix.ArrayLength{Minimum: 1, Maximum: 5},
			},
			Items: &valix.PropertyValidator{
				Type: valix.String,
				Constraints: valix.Constraints{
					&valix.StringLength{Minimum: 2, Maximum: 20},
				},
			},
		},
	},
}

实际应用示例

func validateUserInput(input []byte) error {
	validator := &valix.Validator{
		IgnoreUnknownProperties: false, // 不允许未知属性
		Properties: valix.Properties{
			"username": {
				Type:      valix.String,
				NotNull:   true,
				Mandatory: true,
				Constraints: valix.Constraints{
					&valix.StringLength{Minimum: 4, Maximum: 20},
					&valix.StringPattern{Regexp: `^[a-zA-Z0-9_]+$`},
				},
			},
			"password": {
				Type:      valix.String,
				NotNull:   true,
				Mandatory: true,
				Constraints: valix.Constraints{
					&valix.StringLength{Minimum: 8},
					&valix.StringPattern{
						Regexp: `^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$`,
						Message: "必须包含大小写字母和数字",
					},
				},
			},
			"preferences": {
				Type:    valix.Object,
				NotNull: false,
				ObjectValidator: &valix.Validator{
					Properties: valix.Properties{
						"theme": {
							Type: valix.String,
							Constraints: valix.Constraints{
								&valix.StringOneOf{Choices: []string{"light", "dark", "system"}},
							},
						},
					},
				},
			},
		},
	}

	violations := validator.Validate(string(input))
	if len(violations) > 0 {
		// 将验证错误转换为自定义错误类型
		var errs []error
		for _, v := range violations {
			errs = append(errs, fmt.Errorf("%s: %s", v.Property, v.Message))
		}
		return fmt.Errorf("验证错误: %v", errs)
	}
	return nil
}

valix 提供了非常灵活的验证方式,可以满足大多数 JSON 数据验证需求。它的主要优势在于:

  1. 丰富的内置验证规则
  2. 支持复杂的条件验证
  3. 良好的错误信息反馈
  4. 支持嵌套结构和数组验证
  5. 高性能

对于需要严格验证 JSON 输入的 Go 应用程序,valix 是一个值得考虑的选择。

回到顶部