When the validation field does not exist
struct
type Request struct {
Name string `json:"name" validate:"optional_not_empty"`
Email string `json:"email"`
}
How Customize one optional_not_empty to achieve the following results?
cases
testCases := []Request{
{ Email: ""}, // The Name field is not inpassed, and the verification is passed
{Name: "John", Email: ""}, // Name is passed in and the verification passes
{Name: "", Email: ""}, // Name is passed in, but the value is blank and the verification fails
}
Interesting scenario...
I'd love to see solutions from our community!
Personally, I would create a custom validator for this case.
It's possible to do
type Request struct {
Name *string `json:"name" validate:"omitempty,gt=0"`
Email string `json:"email"`
}
I am not sure if there is any other way how to do it. If you have to separate logic for not exist and null value, sadly with go we can do only this or using something like sql.Null types.
@nodivbyzero Hello, I can only tell if I have this field in my struct by the address right now, but I don't feel good about that, It's like this
func validateOptionalNotEmpty(fl valid.FieldLevel) bool {
// Gets the value of the field 获取字段的值
field := fl.Field()
if field.Kind() == reflect.Ptr && field.IsNil() {
return true
}
// If the field is passed in, check if its value is empty 如果字段传入了,则检查其值是否为空
switch field.Kind() {
case reflect.String:
return field.String() != ""
case reflect.Slice, reflect.Map, reflect.Array:
return field.Len() > 0
case reflect.Ptr, reflect.Interface:
return !field.IsNil()
default:
return true // Other types pass by default 其他类型默认通过
}
}
......
func (v *CustomValidator) lazyInit() {
v.Once.Do(func() {
v.Validate = valid.New()
v.Validate.SetTagName("binding")
// Register a custom validation rule 注册自定义校验规则
// optional_not_empty - The Null Test field type should be set to the pointer type 空效验 字段类型要设置为指针类型
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
_ = v.Validate.RegisterValidation("optional_not_empty", validateOptionalNotEmpty, true)
})
}
With RegisterValidation, I can get the Form Struct, which is the Struct I created, but how can I get the JSON data that was passed in for the request?
example:
this is request data:
{
"role_name": "ordinary",
"remark": "user role",
"test": "test filed"
}
this my struct:
type UpdateRoleReq struct {
RoleName string `json:"role_name" binding:""`
Remark string `json:"remark" binding:""`
}
got my original request data via validateOptionalNotEmpty:
func validateOptionalNotEmpty(fl valid.FieldLevel, rawData interface{}) bool {
print(rawData)
// print:
// {
// "role_name": "ordinary",
// "remark": "user role",
// "test": "test filed"
// }
}