Go (Golang) 中的数据验证:库与方法的完整指南
数据验证是任何 Web 应用程序、API 或微服务中至关重要的一部分。在 Go (Golang) 中,此任务既可以通过标准工具解决,也可以借助强大的第三方库。本文将介绍主要方法、流行库,并提供实用的代码示例。
为什么需要在 Go 中进行验证?
Go 是一种强类型语言,这本身就提供了一定的防止错误数据的保护。然而,类型无法检查业务规则:电子邮件必须包含“@”,年龄必须在 0-120 范围内,密码必须具有最小长度。没有验证,您可能会面临:
- SQL 注入和 XSS 攻击
- 数据库中的错误数据
- 意外的 panic 和运行时错误
内置验证工具
最简单的验证是在函数中“手动”完成的。示例:
type User struct { Name string Email string Age int}
func ValidateUser(u User) error { if u.Name == "" { return errors.New("name is required") } if !strings.Contains(u.Email, "@") { return errors.New("invalid email") } if u.Age < 0 || u.Age > 150 { return errors.New("age must be between 0 and 150") } return nil}这种方法很简单,但对于复杂的结构体来说会变得冗长且难以维护。因此,Go 社区创建了专门的库。
1. go-playground/validator — 事实上的标准
链接: github.com/go-playground/validator/v10
这是 Go 中最流行的验证库(在 GitHub 上拥有超过 15k 星)。它使用结构体标签(struct tags)来声明式地描述规则。
安装
go get github.com/go-playground/validator/v10使用示例
package main
import ( "fmt" "github.com/go-playground/validator/v10")
type User struct { Name string `validate:"required,min=2,max=50"` Email string `validate:"required,email"` Age int `validate:"gte=0,lte=150"` Password string `validate:"required,min=8"`}
func main() { validate := validator.New()
user := User{ Name: "A", Email: "not-email", Age: 200, Password: "123", }
err := validate.Struct(user) if err != nil { for _, e := range err.(validator.ValidationErrors) { fmt.Printf("字段: %s, 规则: %s, 值: %v", e.Field(), e.Tag(), e.Value()) } }}输出:
字段: Name, 规则: min, 值: A字段: Email, 规则: email, 值: not-email字段: Age, 规则: lte, 值: 200字段: Password, 规则: min, 值: 123流行的标签规则
required— 字段必填min,max— 用于数字和字符串len— 精确长度email— 电子邮件验证url— URL 验证gte,lte— 大于/小于或等于oneof— 值之一(oneof=admin user)
自定义验证器
validate.RegisterValidation("is-odd", func(fl validator.FieldLevel) bool { return fl.Field().Int()%2 != 0})
type MyStruct struct { Number int `validate:"is-odd"`}2. ozzo-validation — 链式调用的替代方案
链接: github.com/go-ozzo/ozzo-validation/v4
该库提供了一种更“Go 风格”的方法:规则通过函数而不是标签来定义。这提供了更大的灵活性和可读性。
示例
package main
import ( "fm