golang基于简单规则验证请求数据的高效插件库govalidator的使用

Golang基于简单规则验证请求数据的高效插件库govalidator的使用

简介

govalidator是一个用于验证Golang请求数据的库,它使用简单的规则进行验证,高度受Laravel请求验证的启发。

govalidator

安装

使用以下命令安装该包:

$ go get github.com/thedevsaddam/govalidator
// 或者
$ go get gopkg.in/thedevsaddam/govalidator.v1

使用

要在代码中使用该包,请导入:

import "github.com/thedevsaddam/govalidator"
// 或者
import "gopkg.in/thedevsaddam/govalidator.v1"

示例

验证form-data、x-www-form-urlencoded和查询参数

package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/thedevsaddam/govalidator"
)

func handler(w http.ResponseWriter, r *http.Request) {
	rules := govalidator.MapData{
		"username": []string{"required", "between:3,8"},
		"email":    []string{"required", "min:4", "max:20", "email"},
		"web":      []string{"url"},
		"phone":    []string{"digits:11"},
		"agree":    []string{"bool"},
		"dob":      []string{"date"},
	}

	messages := govalidator.MapData{
		"username": []string{"required:您必须提供用户名", "between:用户名必须在3-8个字符之间"},
		"phone":    []string{"digits:电话号码必须是11位数字"},
	}

	opts := govalidator.Options{
		Request:         r,        // 请求对象
		Rules:           rules,    // 规则映射
		Messages:        messages, // 自定义消息映射(可选)
		RequiredDefault: true,     // 所有字段都必须通过规则
	}
	v := govalidator.New(opts)
	e := v.Validate()
	err := map[string]interface{}{"validationError": e}
	w.Header().Set("Content-type", "application/json")
	json.NewEncoder(w).Encode(err)
}

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("Listening on port: 9000")
	http.ListenAndServe(":9000", nil)
}

使用curl或postman向服务器发送请求:curl GET "http://localhost:9000?web=&phone=&zip=&dob=&agree="

响应

{
    "validationError": {
        "agree": [
            "The agree may only contain boolean value, string or int 0, 1"
        ],
        "dob": [
            "The dob field must be a valid date format. e.g: yyyy-mm-dd, yyyy/mm/dd etc"
        ],
        "email": [
            "The email field is required",
            "The email field must be a valid email address"
        ],
        "phone": [
            "电话号码必须是11位数字"
        ],
        "username": [
            "您必须提供用户名",
            "用户名必须在3-8个字符之间"
        ],
        "web": [
            "The web field format is invalid"
        ]
    }
}

验证规则

  • alpha 验证字段必须完全由字母字符组成
  • alpha_dash 验证字段可以包含字母数字字符以及破折号和下划线
  • alpha_space 验证字段可以包含字母数字字符以及破折号、下划线和空格
  • alpha_num 验证字段必须完全由字母数字字符组成
  • between:numeric,numeric 验证字段的字符长度/数组、切片、映射的长度/两个整数或浮点数之间的范围等
  • numeric 验证字段必须完全由数字字符组成
  • numeric_between:numeric,numeric 验证字段必须是范围内的数值
  • bool 验证字段必须能够转换为布尔值
  • credit_card 验证字段必须具有有效的信用卡号
  • coordinate 验证字段必须具有有效的坐标值
  • css_color 验证字段必须具有有效的CSS颜色值
  • date 验证字段必须具有格式为yyyy-mm-dd或yyyy/mm/dd的有效日期
  • date:dd-mm-yyyy 验证字段必须具有格式为dd-mm-yyyy的有效日期
  • digits:int 验证字段必须是数字且必须具有精确的长度值
  • digits_between:int,int 验证字段必须是数字且长度必须在范围内
  • in:foo,bar 验证字段必须具有其中一个值
  • not_in:foo,bar 验证字段必须具有除foo,bar之外的一个值
  • email 验证字段必须具有有效的电子邮件
  • float 验证字段必须具有有效的浮点数
  • mac_address 验证字段必须是有效的Mac地址
  • min:numeric 验证字段对于字符串必须具有最小字符长度,对于切片/映射必须具有最小项目长度,对于整数或浮点数必须具有最小值
  • max:numeric 验证字段对于字符串必须具有最大字符长度,对于切片/映射必须具有最大项目长度,对于整数或浮点数必须具有最大值
  • len:numeric 验证字段必须具有精确的字符长度、精确的整数或浮点数值、精确的映射/切片大小
  • ip 验证字段必须是有效的IP地址
  • ip_v4 验证字段必须是有效的IP V4地址
  • ip_v6 验证字段必须是有效的IP V6地址
  • json 验证字段必须是有效的JSON字符串
  • lat 验证字段必须是有效的纬度
  • lon 验证字段必须是有效的经度
  • regex:regular expression 根据正则表达式验证字段
  • required 验证字段必须存在于输入数据中且不为空
  • size:integer 验证文件大小(仅限form-data)
  • ext:jpg,png 验证文件扩展名
  • mime:image/jpg,image/png 验证文件的mime类型
  • url 验证字段必须是有效的URL
  • uuid 验证字段必须是有效的UUID
  • uuid_v3 验证字段必须是有效的UUID V3
  • uuid_v4 验证字段必须是有效的UUID V4
  • uuid_v5 验证字段必须是有效的UUID V5

添加自定义规则

func init() {
	// 简单示例
	govalidator.AddCustomRule("must_john", func(field string, rule string, message string, value interface{}) error {
		val := value.(string)
		if val != "john" || val != "John" {
			return fmt.Errorf("The %s field must be John or john", field)
		}
		return nil
	})

	// 自定义规则以获取固定长度的单词
	// 例如:word:5 如果字段不包含确切的5个单词,将抛出错误
	govalidator.AddCustomRule("word", func(field string, rule string, message string, value interface{}) error {
		valSlice := strings.Fields(value.(string))
		l, _ := strconv.Atoi(strings.TrimPrefix(rule, "word:")) //处理其他错误
		if len(valSlice) != l {
			return fmt.Errorf("The %s field must be %d word", field, l)
		}
		return nil
	})
}

注意:可以通过添加自定义规则来验证数组、映射、切片。

自定义消息/本地化

如果需要翻译验证消息,可以将消息作为选项传递:

messages := govalidator.MapData{
	"username": []string{"required:您必须提供用户名", "between:用户名字段必须在3到8个字符之间"},
	"zip":      []string{"numeric:请将zip字段作为数字提供"},
}

opts := govalidator.Options{
	Messages:        messages,
}

更多关于golang基于简单规则验证请求数据的高效插件库govalidator的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于简单规则验证请求数据的高效插件库govalidator的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang数据验证库govalidator使用指南

govalidator是一个轻量级但功能强大的Go语言数据验证库,它提供了简单直观的方式来验证各种数据类型。下面我将介绍它的主要功能和用法。

安装

go get github.com/asaskevich/govalidator

基本验证

字符串验证

package main

import (
	"fmt"
	"github.com/asaskevich/govalidator"
)

func main() {
	// 验证是否为电子邮件
	fmt.Println(govalidator.IsEmail("test@example.com")) // true
	
	// 验证是否为URL
	fmt.Println(govalidator.IsURL("http://example.com")) // true
	
	// 验证是否为IP地址
	fmt.Println(govalidator.IsIP("192.168.1.1")) // true
	
	// 验证是否为字母
	fmt.Println(govalidator.IsAlpha("abc")) // true
	
	// 验证是否为数字
	fmt.Println(govalidator.IsNumeric("123")) // true
	
	// 验证是否为字母或数字
	fmt.Println(govalidator.IsAlphanumeric("abc123")) // true
}

数字验证

// 验证是否为整数
fmt.Println(govalidator.IsInt("123")) // true

// 验证是否为浮点数
fmt.Println(govalidator.IsFloat("123.45")) // true

// 验证数字范围
fmt.Println(govalidator.InRange(5, 1, 10)) // true

结构体验证

govalidator可以很方便地验证结构体字段:

package main

import (
	"fmt"
	"github.com/asaskevich/govalidator"
)

type User struct {
	Name     string `valid:"required,alpha"`
	Age      int    `valid:"required,range(18|99)"`
	Email    string `valid:"required,email"`
	Password string `valid:"required,length(6|20)"`
}

func main() {
	user := User{
		Name:     "John",
		Age:      25,
		Email:    "john@example.com",
		Password: "secret123",
	}

	result, err := govalidator.ValidateStruct(user)
	if err != nil {
		fmt.Println("Validation error:", err)
	} else {
		fmt.Println("Validation passed:", result)
	}
}

自定义验证规则

你可以创建自定义验证函数:

package main

import (
	"fmt"
	"github.com/asaskevich/govalidator"
)

func init() {
	// 注册自定义验证函数
	govalidator.CustomTypeTagMap.Set("custom_validation", func(i interface{}, o interface{}) bool {
		// 这里实现你的验证逻辑
		str, ok := i.(string)
		if !ok {
			return false
		}
		return str == "valid_value"
	})
}

type Data struct {
	Field string `valid:"custom_validation"`
}

func main() {
	data := Data{Field: "valid_value"}
	result, err := govalidator.ValidateStruct(data)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Validation passed:", result)
	}
}

高级功能

验证Map

data := map[string]interface{}{
	"name":  "John",
	"age":   25,
	"email": "john@example.com",
}

rules := map[string]interface{}{
	"name":  "required,alpha",
	"age":   "required,numeric,min(18)",
	"email": "required,email",
}

result := govalidator.ValidateMap(data, rules)
fmt.Println("Validation result:", result)

数据清理

// 清理HTML标签
clean := govalidator.SanitizeHtml("<script>alert('xss')</script>")
fmt.Println(clean) // alert('xss')

// 清理非字母字符
clean = govalidator.Alpha("abc123")
fmt.Println(clean) // abc

性能考虑

govalidator性能较好,但在高并发场景下可以考虑:

  1. 预编译验证规则
  2. 重用验证器实例
  3. 避免在热路径上频繁创建验证器

总结

govalidator提供了:

  • 丰富的内置验证规则
  • 简单的结构体验证
  • 自定义验证支持
  • 数据清理功能
  • Map验证能力

它非常适合用于API请求参数验证、表单验证等场景,既简单又灵活。

回到顶部