英文:
Using validator to check if value is boolean
问题
我是新手,对Go不太熟悉,所以这可能很简单,但我找不到答案。我有一个名为Page
的实体,有两个属性:
type Page struct {
Title string `form:"title" binding:"required"`
Active bool
}
现在,如果你不发送标题,我们会得到一个(不太好看,但可以接受的)错误信息:
Key: 'Page.Title' Error:Field validation for 'Title' failed on the 'required' tag
。
现在,如果我将以下内容发送到端点:
{
"title": "我是一个有效的标题",
"active": "我根本不是布尔值!"
}
我们会得到以下错误信息:
json: cannot unmarshal string into Go struct field Page.Active of type bool
。
在我看来,这提供了太多的信息。在Go中,验证用户输入的标准做法是什么?
我最初创建了一个page-validator.go
文件进行一些检查,然后我找到了这个方法,但我不确定在Go中什么是最佳实践。
我应该如何正确验证这个输入?我应该检查提供的内容,然后尝试将其移入结构体并验证实际内容吗?
我正在使用GinGonic。
-
我找到了一种方法来解析错误并使其更友好。
英文:
I'm new to Go, so this might be very easy, but I can't find it. I have an entity Page
with these two properties:
type Page struct {
Title string `form:"title" binding:"required"`
Active bool
}
Now, if you don't send a title we get a (not very pretty, but acceptable*):
Key: 'Page.Title' Error:Field validation for 'Title' failed on the 'required' tag
.
Now, if I send this to the endpoint:
{
"title": "I'm a valid title",
"active": "I'm not a boolean at all!"
}
We get this:
json: cannot unmarshal string into Go struct field Page.Active of type bool
Which, IMO, is giving way too much info. What is the standard practice in Go to validate user input?
I was first making a page-validor.go
with some checks, then I found this, but I'm not sure what is good practice in Go.
How do I validate this properly? Should I find check what is provided and then try to move it into the struct and validate the actual contents?
I am using GinGonic
* I've found a way to unwrap the errors and make it nicer
答案1
得分: 1
为类型Page
编写自定义的JSON解组方法,并在UnmarshalJSON(bytes []byte)
方法内部,将JSON字节解组为map[string]interface{}
,然后使用JSON字段键验证所需的类型。
JSON解组器的示例如下所示。
type Page struct {
Title string `form:"title" binding:"required"`
Active bool
}
func (p *Page) UnmarshalJSON(bytes []byte) error {
var data map[string]interface{}
err := json.Unmarshal(bytes, &data)
if err != nil {
return err
}
actv, _ := data["active"]
if reflect.TypeOf(actv).Kind() != reflect.Bool {
return errors.New("active field should be a boolean")
}
p.Active = actv.(bool)
return nil
}
在Playground中查看完整示例。
英文:
Write custom JSON Unmarshaller method for the type Page
and inside UnmarshalJSON(bytes []byte)
method, you can unmarshal the JSON bytes to map[string]interface{}
and then validate the types you need with the JSON field keys.
An example of the JSON Unmarshaller looks like below.
type Page struct {
Title string `form:"title" binding:"required"`
Active bool
}
func (p *Page) UnmarshalJSON(bytes []byte) error {
var data map[string]interface{}
err := json.Unmarshal(bytes, &data)
if err != nil {
return err
}
actv, _ := data["active"]
if reflect.TypeOf(actv).Kind() != reflect.Bool {
return errors.New("active field should be a boolean")
}
p.Active = actv.(bool)
return nil
}
See the full example here in Playground.
答案2
得分: 1
经过进一步的研究,我已经实现了Go-map-schema。
var page Page
src := make(map[string]interface{})
json.Unmarshal(jsonData, &src)
results, _ := schema.CompareMapToStruct(page, src, nil)
fmt.Println(results.MissingFields)
fmt.Println(results.MismatchedFields)
这个代码片段使用了结构体的标准表示方式:
type Page struct {
Title string `json:"title" validator:"required"`
Active bool `json:"metaRobotsFollow" validate:"required,bool"`
}
英文:
After some more research, I've implemented Go-map-schema.
var page Page
src := make(map[string]interface{})
json.Unmarshal(jsonData, &src)
results, _ := schema.CompareMapToStruct(page, src, nil)
fmt.Println(results.MissingFields)
fmt.Println(results.MismatchedFields)
This works simple with the standard notations for an struct:
type Page struct {
Title string `json:"title" validator:"required"`
Active bool `json:"metaRobotsFollow" validate:"required,bool"`
}
答案3
得分: 0
你应该使用Go中可用的validator v10。
对于你的用例,你可以使用boolean验证器。
https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Boolean
type Page struct {
Title string `json:"title" binding:"required"`
Active bool `json:"active" binding:"required,boolean"`
}
以下是一个带有一个正向和一个负向测试用例的示例:
func TestPage(t *testing.T) {
tests := []struct {
testName string
input string
wantErr bool
}{
{
testName: "positive test",
input: `{
"title": "first book title",
"active": false
}`,
wantErr: false,
}, {
testName: "wrong boolean",
input: `{
"title": "second book title",
"active": falsee
}`,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
var p Page
b := []byte(tt.input)
err := json.Unmarshal(b, &p)
assert.Nil(t, err, "got error %v", err)
})
}
}
英文:
You should use validator v10 available with Go
For your use case you can use boolean validator
https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Boolean
type Page struct {
Title string `json:"title" binding:"required"`
Active bool `json:"active" binding:"required,boolean"`
}
Below is sample Test case with one positive and negative
func TestPage(t *testing.T) {
tests := []struct {
testName string
input string
wantErr bool
}{
{
testName: "positive test",
input: `{
"title": "first book title",
"active": false
}`,
wantErr: false,
}, {
testName: "wrong boolean",
input: `{
"title": "second book title",
"active": falsee
}`,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
var p Page
b := []byte(tt.input)
err := json.Unmarshal(b, &p)
assert.Nil(t, err, "got error %v", err)
})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论