golang轻量级结构体验证插件库gody的使用
golang轻量级结构体验证插件库gody的使用
安装
go get github.com/guiferpa/gody/v2
使用示例
下面是一个完整的HTTP服务示例,展示如何使用gody进行结构体验证:
package main
import (
"encoding/json"
"fmt"
"net/http"
gody "github.com/guiferpa/gody/v2"
"github.com/guiferpa/gody/v2/rule"
)
// 定义请求体结构
type RequestBody struct {
Name string `json:"name" validate:"not_empty"` // 验证name字段不能为空
Age int `json:"age" validate:"min=21"` // 验证age字段最小值为21
}
// HTTP处理函数
func HTTPHandler(v *gody.Validator) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var body RequestBody
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
defer r.Body.Close()
// 验证请求体
if isValidated, err := v.Validate(body); err != nil {
http.Error(w, fmt.Sprintf("Validation error: %v", err), http.StatusBadRequest)
return
} else if !isValidated {
http.Error(w, "Validation failed", http.StatusBadRequest)
return
}
// 验证通过的处理逻辑
fmt.Fprintf(w, "Validation passed! Name: %s, Age: %d", body.Name, body.Age)
})
}
func main() {
// 创建验证器实例
validator := gody.NewValidator()
// 添加验证规则
validator.AddRules(rule.NotEmpty, rule.Min)
// 启动HTTP服务
port := ":3000"
fmt.Printf("Server started on port %s\n", port)
http.ListenAndServe(port, HTTPHandler(validator))
}
其他验证方式
gody提供了多种验证函数:
- RawValidate - 无需预定义规则的验证函数,需要传入结构体、标签名和规则列表
gody.RawValidate(interface{}, string, []gody.Rule) (bool, error)
- Validate - 无需预定义规则的验证函数,需要传入结构体和规则列表
gody.Validate(interface{}, []gody.Rule) (bool, error)
- RawDefaultValidate - 使用内置规则的验证函数,需要传入结构体、标签名和可选的自定义规则
gody.RawDefaultValidate(interface{}, string, []gody.Rule) (bool, error)
- DefaultValidate - 使用内置规则的验证函数,需要传入结构体和可选的自定义规则
gody.DefaultValidate(interface{}, []gody.Rule) (bool, error)
动态枚举验证(避免重复)
可以通过动态参数避免在结构体标签中重复枚举值:
const (
StatusCreated = "__CREATED__"
StatusPending = "__PENDING__"
StatusDoing = "__DOING__"
StatusDone = "__DONE__"
)
type Task struct {
Name string `json:"name"`
Status string `json:"status" validate:"enum={status}"` // 使用动态参数
}
validator := gody.NewValidator()
validator.AddRuleParameters(map[string]string{
"status": fmt.Sprintf("%s,%s,%s,%s", StatusCreated, StatusPending, StatusDoing, StatusDone),
})
validator.AddRules(rule.Enum)
// 现在可以验证Task结构体而无需在标签中重复枚举值
贡献政策
- 目前唯一的政策是不要直接创建Pull Request,在实现之前需要通过issue进行讨论。
更多关于golang轻量级结构体验证插件库gody的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang轻量级结构体验证插件库gody的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go轻量级结构体验证库 - gody 使用指南
gody 是一个轻量级的 Go 结构体验证库,它简单易用且不依赖反射,适合需要快速验证结构体数据的场景。
安装
go get github.com/guiferpa/gody
基本使用
1. 简单验证
package main
import (
"fmt"
"github.com/guiferpa/gody"
)
type User struct {
Name string `json:"name" validate:"not_empty"`
Email string `json:"email" validate:"not_empty,email"`
Age int `json:"age" validate:"min=18"`
}
func main() {
user := User{
Name: "John Doe",
Email: "john@example.com",
Age: 25,
}
// 注册默认验证规则
gody.RegisterDefaultRules()
// 验证结构体
if err := gody.Validate(user); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation passed!")
}
}
2. 内置验证规则
gody 提供了一些内置验证规则:
not_empty
- 字段不能为空email
- 必须是有效的电子邮件格式min
- 数字最小值 (如min=18
)max
- 数字最大值 (如max=100
)len
- 字符串长度 (如len=10
)uuid
- 必须是有效的UUIDregexp
- 正则表达式匹配 (如regexp=^[a-zA-Z]+$
)
3. 自定义验证规则
package main
import (
"fmt"
"github.com/guiferpa/gody"
"strings"
)
type Product struct {
Code string `json:"code" validate:"not_empty,starts_with_P"`
Price int `json:"price" validate:"min=1"`
}
// 自定义验证函数
func startsWithP(rule string, value interface{}) error {
s, ok := value.(string)
if !ok {
return fmt.Errorf("starts_with_P: value must be a string")
}
if !strings.HasPrefix(s, "P") {
return fmt.Errorf("starts_with_P: value must start with 'P'")
}
return nil
}
func main() {
product := Product{
Code: "P12345",
Price: 100,
}
// 注册默认规则
gody.RegisterDefaultRules()
// 注册自定义规则
gody.RegisterRule("starts_with_P", startsWithP)
if err := gody.Validate(product); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation passed!")
}
}
4. 验证嵌套结构体
package main
import (
"fmt"
"github.com/guiferpa/gody"
)
type Address struct {
Street string `json:"street" validate:"not_empty"`
City string `json:"city" validate:"not_empty"`
}
type Customer struct {
Name string `json:"name" validate:"not_empty"`
Address Address `json:"address" validate:"struct"`
}
func main() {
customer := Customer{
Name: "Jane Smith",
Address: Address{
Street: "123 Main St",
City: "",
},
}
gody.RegisterDefaultRules()
if err := gody.Validate(customer); err != nil {
fmt.Println("Validation error:", err)
// 输出: Validation error: address.city: cannot be empty
}
}
5. 切片验证
package main
import (
"fmt"
"github.com/guiferpa/gody"
)
type Item struct {
ID string `json:"id" validate:"not_empty,uuid"`
Name string `json:"name" validate:"not_empty"`
Count int `json:"count" validate:"min=1"`
}
type Order struct {
Items []Item `json:"items" validate:"not_empty"`
}
func main() {
order := Order{
Items: []Item{
{
ID: "550e8400-e29b-41d4-a716-446655440000",
Name: "Laptop",
Count: 1,
},
{
ID: "",
Name: "Mouse",
Count: 0,
},
},
}
gody.RegisterDefaultRules()
if err := gody.Validate(order); err != nil {
fmt.Println("Validation error:", err)
// 输出: Validation error: items[1].id: cannot be empty; items[1].count: must be greater than or equal to 1
}
}
性能考虑
gody 相比其他验证库(如 go-playground/validator)有以下特点:
- 不使用反射,性能更好
- 验证规则更简单,功能相对较少
- 适合简单到中等复杂度的验证需求
总结
gody 是一个轻量级的验证库,适合那些:
- 需要简单快速验证的场景
- 对性能有要求的应用
- 不需要复杂验证逻辑的项目
对于更复杂的验证需求,可能需要考虑其他功能更全面的验证库。但如果你需要一个小巧、快速的验证工具,gody 是一个不错的选择。