简体   繁体   English

使用验证器检查值是否为 boolean

[英]Using validator to check if value is boolean

I'm new to Go, so this might be very easy, but I can't find it.我是 Go 的新手,所以这可能很容易,但我找不到。 I have an entity Page with these two values:我有一个具有这两个值的实体Page

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 . 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.哪个,IMO,提供了太多信息。 What is the standard practice in Go to validate user input? Go 中验证用户输入的标准做法是什么?

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.我首先制作了一个page-validor.go并进行了一些检查,然后我发现了这个,但我不确定 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我正在使用GinGonic
* I've found a way to unwrap the errors and make it nicer * 我找到了一种方法来解开错误并让它变得更好

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. 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. JSON Unmarshaller 的示例如下所示。

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 .请参阅Playground中的完整示例。

After some more research, I've implementedGo-map-schema .经过更多研究,我实现了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" validator:"required,bool"`
}

You should use validator v10 available with Go您应该使用 Go 提供的验证器 v10

validator documentation go验证器文档 go

For your use case you can use boolean validator对于您的用例,您可以使用boolean验证器
https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-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"`
}

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)
    })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM