[英]Golang: Validate inner Struct field based on the values of one of its enclosing struct's field using required_if tag
[英]Golang: Validate Struct field of type string to be one of specific values
golang 版本: 1.18.3
驗證器: github.com/go-playground/validator/v10
我想在加載到嵌套結構數據結構后驗證傳入的 JSON 有效負載。 這是我傳入的 JSON 有效負載,
{
"name": "Duro",
"gender": "MALE",
"tier": 3,
"mobileNumber": "0356874586",
"address": {
"city": "Tokyo",
"street": "Shibaura St"
},
"children":[
{
"title": "Mr",
"lastName": "Takayashi"
}
],
"isEmployed": false,
"requestedAt": "2022-01-10T03:30:12.639Z"
}
這是我的 user.go 文件,
package main
type User struct {
Name string `validate:"required"`
Gender string `validate:"required,oneof=MALE FEMALE"`
Tier *uint8 `validate:"required,eq=0|eq=1|eq=2|eq=3"`
MobileNumber string `validate:"required"`
Email string
Address *Address `validate:"required"`
Children []Child `validate:"required,dive"`
IsEmployed *bool `validate:"required"`
PreferredContactMethod string `validate:"oneof=EMAIL PHONE POST SMS"`
RequestedAt time.Time `validate:"required"`
}
type Address struct {
City string `validate:"required"`
Street string `validate:"required"`
}
type Child struct {
Title string `validate:"required"`
FirstName string
LastName string `validate:"required"`
}
這是我的測試功能
func TestUserPayload(t *testing.T) {
validate := validator.New()
var u User
err := json.Unmarshal([]byte(jsonData), &u)
if err != nil {
panic(err)
}
err := validate.Struct(&u)
if err != nil {
t.Errorf("error %v", err)
}
}
此測試因錯誤而失敗,
error Key: 'User.PreferredContactMethod' Error:Field validation for 'PreferredContactMethod' failed on the 'oneof' tag
發生這種情況是因為 Go 將空字符串分配給 User.PreferredContactMethod 結構字段。 由於PreferredContactMethod
不是必填字段,因此當 json 有效負載沒有它時,我不想看到此驗證錯誤。 當 json 有效負載沒有preferredContactMethod
字段時,如何避免此錯誤消息?
如果您有更好的選擇來實現此驗證,也很高興聽到它們。
使用omitempty
和oneof
使驗證器庫忽略空值或未設置值。
type User struct {
Name string `validate:"required"`
Gender string `validate:"required,oneof=MALE FEMALE"`
Tier *uint8 `validate:"required,eq=0|eq=1|eq=2|eq=3"`
MobileNumber string `validate:"required"`
Email string
Address *Address `validate:"required"`
Children []Child `validate:"required,dive"`
IsEmployed *bool `validate:"required"`
PreferredContactMethod string `validate:"omitempty,oneof=EMAIL PHONE POST SMS"`
RequestedAt time.Time `validate:"required"`
}
使用https://github.com/marrow16/valix ( https://pkg.go.dev/github.com/marrow16/valix ) 可以通過以下方式實現:
package main
import (
"fmt"
"time"
"github.com/marrow16/valix"
)
type User struct {
Name string `json:"name" v8n:"required, notNull"`
Gender string `json:"gender" v8n:"required, notNull, &strtoken{['MALE','FEMALE']}"`
Tier uint8 `json:"tier" v8n:"required, notNull, &mini{0}, &maxi{3}"`
DateOfBirth string `json:"dateOfBirth" v8n:"notNull, &strisod"`
MobileNumber string `json:"mobileNumber" v8n:"required, notNull, &strpatt{'^([0-9]{8,16})$'}"`
Email string `json:"email" v8n:"notNull"`
Address Address `json:"address" v8n:"required, notNull"`
Children []Child `json:"children" v8n:"required, notNull"`
IsEmployed bool `json:"isEmployed" v8n:"required"`
PreferredContactMethod string `json:"preferredContactMethod" v8n:"notNull, &strtoken{['EMAIL','PHONE','POST','SMS']}"`
RequestedAt time.Time `json:"requestedAt" v8n:"required, notNull, &strisodt"`
}
type Address struct {
City string `json:"city" v8n:"required, notNull"`
Street string `json:"street" v8n:"required, notNull"`
}
type Child struct {
Title string `json:"title" v8n:"required, notNull"`
FirstName string `json:"firstName" v8n:"notNull"`
LastName string `json:"lastName" v8n:"required, notNull"`
}
const jsonData = `{
"name": "Duro",
"gender": "MALE",
"tier": 3,
"dateOfBirth": "2000-01-13",
"mobileNumber": "0356874586",
"address": {
"city": "Tokyo",
"street": "Shibaura St"
},
"children":[
{
"title": "Mr",
"lastName": "Takayashi"
}
],
"isEmployed": false,
"requestedAt": "2022-01-10T03:30:12.639Z"
}`
var UserRequestValidator = valix.MustCompileValidatorFor(User{}, nil)
func main() {
user := User{}
ok, violations, _ := UserRequestValidator.ValidateStringInto(jsonData, &user)
if ok {
fmt.Println("Validation successful")
} else {
fmt.Println(fmt.Sprintf("Validation failed! (violations: %d)", len(violations)))
for _, v := range violations {
fmt.Printf("%s (property: '%s', path: '%s')\n", v.Message, v.Property, v.Path)
}
}
}
去游樂場: https ://go.dev/play/p/3zrkZx97m-e
披露:我是 Valix 的作者
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.