Hi guys. I have the following problem
type Foo struct {
Bar bool `json:"bar" binding:"required"` // True / False
}
When I send a JSON request with the value true it works, but when I send the same request with false I get the following error.
{
"error": {
"Foo.Bar": {
"FieldNamespace": "Foo.Bar",
"NameNamespace": "Bar",
"Field": "Bar",
"Name": "Bar",
"Tag": "required",
"ActualTag": "required",
"Kind": 1,
"Type": {},
"Param": "",
"Value": false
}
}
},
Comment From: deankarn
I'll refer you to:
685
611
In summary you need a pointer or custom type to know if the value exists due to Go's static nature.
Comment From: appleboy
Change bool
to *bool
Comment From: bardia-key
Just an update to whomever is still stuck with this bug. Addind *bool is not the entire solution. You must change the binding:"required"
to binding:"exists"
.
Here is the documentation to back that up (gin uses this pkg for input obj validations): https://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Exists
Comment From: deankarn
Thanks @bkeyoumarsi
to further this answer exists
was removed in v9 and required
works with *bool
I highly recommend updating to v9, there were many performance updates and changes for ease of use :)
see https://github.com/go-playground/validator/tree/v9/examples/gin-upgrading-overriding for updating gin to use v9 of validator.
Comment From: EsonChurch
wtf
Comment From: sawtamlahtoo
man fuck this shit
Comment From: rickyManalo
This seems to still be happening. I already have the latest version and added both * and binding:"required" to the field and the field is still not getting returned
UPDATE: It seems my issue wasn't caused by gin itself, but because of the generated files of protobuf adding omitempty on all fields
Comment From: cohendvir
here too :/
Comment From: matisiekpl
Is there any update here? Adding ,omitempty
still does not fix the bug 😢
Comment From: appleboy
@matisiekpl What is your problem? I think the comment can fix the issue.
Comment From: forbesd7
This is my understanding for why we use *bool rather than bool to anyone who might be wondering:
Golang gives booleans a default value of 'false' so if a value in JSON has 'false' there isn't a way to differentiate between the default value and an actual false value. So by using a pointer we can differentiate between the default value of '&false' and nil (default value for unset pointer)
With *Bool
type Todo struct {
Done *bool `json:"done" binding:"required"`
}
// These JSON inputs would result in:
{"done": true} -> Done: &true
{"done": false} -> Done: &false
{} -> Done: nil
With Bool
type Todo struct {
Done bool `json:"done" binding:"required"`
}
// These JSON inputs would result in:
{"done": true} -> Done: true
{"done": false} -> Done: false
{} -> Done: false // (default/zero value)
Please let me know if this understanding is wrong/misleading :) @appleboy @deankarn