[英]Golang: Validate Struct field of type string to be one of specific values
golang version: 1.18.3
golang 版本: 1.18.3
validator: github.com/go-playground/validator/v10
验证器: github.com/go-playground/validator/v10
I want to validate an incoming JSON payload after loaded into nested struct data structure.我想在加载到嵌套结构数据结构后验证传入的 JSON 有效负载。 Here's my incoming JSON payload,这是我传入的 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"
}
Here's my user.go file,这是我的 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"`
}
Here's my test function这是我的测试功能
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)
}
}
This test fails with error,此测试因错误而失败,
error Key: 'User.PreferredContactMethod' Error:Field validation for 'PreferredContactMethod' failed on the 'oneof' tag
This happens because Go assigns empty string to User.PreferredContactMethod struct field.发生这种情况是因为 Go 将空字符串分配给 User.PreferredContactMethod 结构字段。 Since PreferredContactMethod
is NOT a required field, I DON'T want to see this validation error when json payload doesn't have it.由于PreferredContactMethod
不是必填字段,因此当 json 有效负载没有它时,我不想看到此验证错误。 How can I avoid this error message when the json payload doesn't have preferredContactMethod
field?当 json 有效负载没有preferredContactMethod
字段时,如何避免此错误消息?
If you have better alternatives to achieve this validation, happy to hear them as well.如果您有更好的选择来实现此验证,也很高兴听到它们。
Utilize omitempty
along with oneof
to make the validator library ignore empty or unset values.使用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"`
}
Using https://github.com/marrow16/valix ( https://pkg.go.dev/github.com/marrow16/valix ) it could be achieved with the following:使用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)
}
}
}
Go playground here: https://go.dev/play/p/3zrkZx97m-e去游乐场: https ://go.dev/play/p/3zrkZx97m-e
Disclosure: I am the author of Valix披露:我是 Valix 的作者
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.