Closed eddiedane closed 10 months ago
@eddiedane not currently, there is no way to early stop validation in this specific way.
There is a way on fields of a struct that are a struct using the structonly
tag, but needs to be a field of a struct in order to have a tag registered.
Usually when people are doing Struct Level validation are not also doing field level using tags that I'm aware of and would validate in the struct level
manually. eg.
type LoginUserDto struct {
Email string
Password string
Remember bool
}
func main() {
validate.RegisterStructValidation(verifyLoginCredentials, LoginUserDto{})
}
func verifyLoginCredentials(sl validator.StructLevel) {
loginData := sl.Current().Interface().(LoginUserDto)
// validate is email, not blank etc. etc..
if loginData.Email == "" {
sl.ReportError(loginData.Email, "Email", "Email", "exists", "")
return
}
// validate other fields.
// query database for user with loginData.Email
var user string
if user == nil {
sl.ReportError(loginData.Email, "Email", "Email", "exists", "")
return
}
// compare loginData.Password with user.HashedPassword
passwordMatched := Compare(loginData.Password, user.HashedPassword)
if !passwordMatched {
sl.ReportError(loginData.Password, "Password", "Password", "checkpassword", "")
return
}
}
The other option would be to to use field level
validations without struct level
as all the database etc validation can also be done there as it has access to the parent struct. eg.
v := validator.New()
v.RegisterValidation("password", func(fl validator.FieldLevel) bool {
loginData := fl.Parent().Interface().(LoginUserDto)
// query database for user with loginData.Email
var user string
if user == nil {
return false
}
// compare loginData.Password with user.HashedPassword
passwordMatched := Compare(loginData.Password, user.HashedPassword)
if !passwordMatched {
return false
}
return false
})
I hope that provides some guidance.
Awesome @deankarn, thanks for your response, I guess using one of the validation levels will do for now, I was following the example on struct level validation, it included both field level and struct level validation, maybe it should be updated to avoid confusion.
Package version
v10.15.0
Issue:
Disclaimer: am fairly new to go-playground/validator
When using field level validation with registered struct validation, it seems both validation level always run which is kind of unnecessary an can lead to unexpected results, like in my current application of these two validation level for login system.
Streamlined Code sample, to showcase or reproduce:
Observations
Now regardless of whether the Email or the Password field fails the field level validation (required i.e they have no value), the struct level validation still executes which very unnecessary and expensive, I also observed that the order of validation is field level first the struct level, which is awesome!
Question
Given that the field level validation executes before the struct level, is there a way to halt the execution of the struct level validations, in cases where the struct level requires/assumes the field level validation to pass