This is a really simple implementation of validation in go
To validate a struct, you can just create a validation method like so:
import "github.com/mfaizudd/nodebat-go/validation"
type Student struct {
name string
}
func (s *Student) Validate() error {
v := validation.New()
v.Add("name", validation.Required(s.name), validation.IsAlphanumeric(s.name))
return v.Error()
}The builder struct provides a way to chain validators easier. The above example can be recreated using builder like so:
import "github.com/mfaizudd/nodebat-go/validation"
type Student struct {
name string
}
func (s *Student) Validate() error {
v := validation.New()
// field , value
v.Builder("name", s.name).Required().IsAlphanumeric()
return v.Error()
}Using the builder, the validator will attempt to convert the type into the correct type,
and if it fails to do so, it will return invalid_integer, invalid_float
invalid_time depending on the validator thats being used
You can use tags to translate the error message
| Validator | Tag |
|---|---|
| Required | required |
| IsAlphanumeric | is_alphanumeric |
| MinLength | min_length |
| MaxLength | max_length |
| Min | min |
| Max | max |
| Range | range |
| OneOf | one_of |
| IsEmail | is_email |
| IsISO8601 | is_iso8601 |
| IsISO8601Date | is_iso8601_date |
| IsPhone | is_phone |
| IsUUID | is_uuid |
| MinDate | min_date |
| MaxDate | max_date |
| BetweenDate | between_date |
To create a custom validation, you simply need to create a function that
returns func(field string) *validation.FieldError.
validation.Validator is just a wrapper type of
func(field string) *validation.FieldError.
Example:
// IsEmail checks if the data is a valid email address
func IsEmail(email string) validation.Validator {
return func(field string) *validation.FieldError {
_, emailErr := mail.ParseAddress(email)
if emailErr != nil {
msg := fmt.Sprintf("%s is not a valid email address", field)
return validation.NewFieldError(field, msg, "is_email", email)
}
return nil
}
}When you're using builder, you can add arbitrary validator
using the Custom method
v.Builder("field", someValue).Custom(SomeCustomValidator("arg1", someValue))Or even create a validator directly
v.Builder("field", someValue).Custom(func(field string) *validation.FieldError {
return nil
})
// or, if not using builder
v.Add("field", func(field string) *validation.FieldError {
return nil
})- Fun,
- It's more flexible than package validator, I think. With this library I can use whatever logic I want in my validation. Like, for example, I can only validate a field if other field is empty, or I can validate a field against a database by providing a database connection dependency in the validation parameters, etc.
- It's simple, my brain can understand this so you can too.
- It still has
tagsto use with universal-translator. I actually made this library because I'm not satisfied with package validator and I only just want to validate some simple thing anyway. - I need a validation library that can return something like what laravel's validation returns.