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
tags
to 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.