validator.v2: gopkg.in/validator.v2 Index | Examples | Files

package validator

import "gopkg.in/validator.v2"

Package validator implements value validations based on struct tags.

In code it is often necessary to validate that a given value is valid before using it for something. A typical example might be something like this.

if age < 18 {
	return error.New("age cannot be under 18")
}

This is a simple enough example, but it can get significantly more complex, especially when dealing with structs.

l := len(strings.Trim(s.Username))
if l < 3 || l > 40  || !regexp.MatchString("^[a-zA-Z]$", s.Username) ||	s.Age < 18 || s.Password {
	return errors.New("Invalid request")
}

You get the idea. Package validator allows one to define valid values as struct tags when defining a new struct type.

type NewUserRequest struct {
	Username string `validate:"min=3,max=40,regexp=^[a-zA-Z]*$"`
	Name string     `validate:"nonzero"`
	Age int         `validate:"min=18"`
	Password string `validate:"min=8"`
}

Then validating a variable of type NewUserRequest becomes trivial.

nur := NewUserRequest{Username: "something", ...}
if errs := validator.Validate(nur); errs != nil {
	// do something
}

Builtin validator functions

Here is the list of validator functions builtin in the package.

len
	For numeric numbers, len will simply make sure that the value is
	equal to the parameter given. For strings, it checks that
	the string length is exactly that number of characters. For slices,
	arrays, and maps, validates the number of items. (Usage: len=10)

max
	For numeric numbers, max will simply make sure that the value is
	lesser or equal to the parameter given. For strings, it checks that
	the string length is at most that number of characters. For slices,
	arrays, and maps, validates the number of items. (Usage: max=10)

min
	For numeric numbers, min will simply make sure that the value is
	greater or equal to the parameter given. For strings, it checks that
	the string length is at least that number of characters. For slices,
	arrays, and maps, validates the number of items. (Usage: min=10)

nonzero
	This validates that the value is not zero. The appropriate zero value
	is given by the Go spec (e.g. for int it's 0, for string it's "", for
	pointers is nil, etc.) Usage: nonzero

regexp
	Only valid for string types, it will validate that the value matches
	the regular expression provided as parameter. (Usage: regexp=^a.*b$)

Note that there are no tests to prevent conflicting validator parameters. For instance, these fields will never be valid.

...
A int     `validate:"max=0,min=1"`
B string  `validate:"len=10,regexp=^$"
...

Custom validation functions

It is possible to define custom validation functions by using SetValidationFunc. First, one needs to create a validation function.

// Very simple validation func
func notZZ(v interface{}, param string) error {
	st := reflect.ValueOf(v)
	if st.Kind() != reflect.String {
		return validate.ErrUnsupported
	}
	if st.String() == "ZZ" {
		return errors.New("value cannot be ZZ")
	}
	return nil
}

Then one needs to add it to the list of validation funcs and give it a "tag" name.

validate.SetValidationFunc("notzz", notZZ)

Then it is possible to use the notzz validation tag. This will print "Field A error: value cannot be ZZ"

type T struct {
	A string  `validate:"nonzero,notzz"`
}
t := T{"ZZ"}
if errs := validator.Validate(t); errs != nil {
	fmt.Printf("Field A error: %s\n", errs["A"][0])
}

To use parameters, it is very similar.

// Very simple validator with parameter
func notSomething(v interface{}, param string) error {
	st := reflect.ValueOf(v)
	if st.Kind() != reflect.String {
		return validate.ErrUnsupported
	}
	if st.String() == param {
		return errors.New("value cannot be " + param)
	}
	return nil
}

And then the code below should print "Field A error: value cannot be ABC".

validator.SetValidationFunc("notsomething", notSomething)
type T struct {
	A string  `validate:"notsomething=ABC"`
}
t := T{"ABC"}
if errs := validator.Validate(t); errs != nil {
	fmt.Printf("Field A error: %s\n", errs["A"][0])
}

As well, it is possible to overwrite builtin validation functions.

validate.SetValidationFunc("min", myMinFunc)

And you can delete a validation function by setting it to nil.

validate.SetValidationFunc("notzz", nil)
validate.SetValidationFunc("nonzero", nil)

Using a non-existing validation func in a field tag will always return false and with error validate.ErrUnknownTag.

Finally, package validator also provides a helper function that can be used to validate simple variables/values.

    	// errs: nil
	errs = validator.Valid(42, "min=10, max=50")

	// errs: [validate.ErrZeroValue]
	errs = validator.Valid(nil, "nonzero")

	// errs: [validate.ErrMin,validate.ErrMax]
	errs = validator.Valid("hi", "nonzero,min=3,max=2")

Custom tag name

In case there is a reason why one would not wish to use tag 'validate' (maybe due to a conflict with a different package), it is possible to tell the package to use a different tag.

validator.SetTag("valid")

Then.

Type T struct {
	A int    `valid:"min=8, max=10"`
	B string `valid:"nonzero"`
}

SetTag is permanent. The new tag name will be used until it is again changed with a new call to SetTag. A way to temporarily use a different tag exists.

validator.WithTag("foo").Validate(t)
validator.WithTag("bar").Validate(t)
// But this will go back to using 'validate'
validator.Validate(t)

Multiple validators

You may often need to have a different set of validation rules for different situations. In all the examples above, we only used the default validator but you could create a new one and set specific rules for it.

For instance, you might use the same struct to decode incoming JSON for a REST API but your needs will change when you're using it to, say, create a new instance in storage vs. when you need to change something.

type User struct {
	Username string `validate:"nonzero"`
	Name string     `validate:"nonzero"`
	Age int         `validate:"nonzero"`
	Password string `validate:"nonzero"`
}

Maybe when creating a new user, you need to make sure all values in the struct are filled, but then you use the same struct to handle incoming requests to, say, change the password, in which case you only need the Username and the Password and don't care for the others. You might use two different validators.

type User struct {
	Username string `creating:"nonzero" chgpw:"nonzero"`
	Name string     `creating:"nonzero"`
	Age int         `creating:"nonzero"`
	Password string `creating:"nonzero" chgpw:"nonzero"`
}

var (
	creationValidator = validator.NewValidator()
	chgPwValidator = validator.NewValidator()
)

func init() {
	creationValidator.SetTag("creating")
	chgPwValidator.SetTag("chgpw")
}

...

func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
	var u User
	json.NewDecoder(r.Body).Decode(&user)
	if errs := creationValidator.Validate(user); errs != nil {
		// the request did not include all of the User
		// struct fields, so send a http.StatusBadRequest
		// back or something
	}
	// create the new user
}

func SetNewUserPasswordHandler(w http.ResponseWriter, r *http.Request) {
	var u User
	json.NewDecoder(r.Body).Decode(&user)
	if errs := chgPwValidator.Validate(user); errs != nil {
		// the request did not Username and Password,
		// so send a http.StatusBadRequest
		// back or something
	}
	// save the new password
}

It is also possible to do all of that using only the default validator as long as SetTag is always called before calling validator.Validate() or you chain the with WithTag().

Index

Examples

Package Files

builtins.go doc.go validator.go

Variables

var (
    // ErrZeroValue is the error returned when variable has zero valud
    // and nonzero was specified
    ErrZeroValue = TextErr{errors.New("zero value")}
    // ErrMin is the error returned when variable is less than mininum
    // value specified
    ErrMin = TextErr{errors.New("less than min")}
    // ErrMax is the error returned when variable is more than
    // maximum specified
    ErrMax = TextErr{errors.New("greater than max")}
    // ErrLen is the error returned when length is not equal to
    // param specified
    ErrLen = TextErr{errors.New("invalid length")}
    // ErrRegexp is the error returned when the value does not
    // match the provided regular expression parameter
    ErrRegexp = TextErr{errors.New("regular expression mismatch")}
    // ErrUnsupported is the error error returned when a validation rule
    // is used with an unsupported variable type
    ErrUnsupported = TextErr{errors.New("unsupported type")}
    // ErrBadParameter is the error returned when an invalid parameter
    // is provided to a validation rule (e.g. a string where an int was
    // expected (max=foo,len=bar) or missing a parameter when one is required (len=))
    ErrBadParameter = TextErr{errors.New("bad parameter")}
    // ErrUnknownTag is the error returned when an unknown tag is found
    ErrUnknownTag = TextErr{errors.New("unknown tag")}
    // ErrInvalid is the error returned when variable is invalid
    // (normally a nil pointer)
    ErrInvalid = TextErr{errors.New("invalid value")}
)

func SetTag Uses

func SetTag(tag string)

SetTag allows you to change the tag name used in structs

This example shows you how to change the tag name

Code:

type T struct {
    A int `foo:"nonzero" bar:"min=10"`
}
t := T{5}
v := validator.NewValidator()
v.SetTag("foo")
err := v.Validate(t)
fmt.Printf("foo --> valid: %v, errs: %v\n", err == nil, err)
v.SetTag("bar")
err = v.Validate(t)
errs := err.(validator.ErrorMap)
fmt.Printf("bar --> valid: %v, errs: %v\n", err == nil, errs)

Output:

foo --> valid: true, errs: <nil>
bar --> valid: false, errs: A: less than min

func SetValidationFunc Uses

func SetValidationFunc(name string, vf ValidationFunc) error

SetValidationFunc sets the function to be used for a given validation constraint. Calling this function with nil vf is the same as removing the constraint function from the list.

func Valid Uses

func Valid(val interface{}, tags string) error

Valid validates a value based on the provided tags and returns errors found or nil.

This example shows how to use the Valid helper function to validator any number of values

Code:

err := validator.Valid(42, "min=10,max=100,nonzero")
fmt.Printf("42: valid=%v, errs=%v\n", err == nil, err)

var ptr *int
if err := validator.Valid(ptr, "nonzero"); err != nil {
    fmt.Println("ptr: Invalid nil pointer.")
}

err = validator.Valid("ABBA", "regexp=[ABC]*")
fmt.Printf("ABBA: valid=%v\n", err == nil)

Output:

42: valid=true, errs=<nil>
ptr: Invalid nil pointer.
ABBA: valid=true

func Validate Uses

func Validate(v interface{}) error

Validate validates the fields of a struct based on 'validator' tags and returns errors found indexed by the field name.

This example demonstrates a custom function to process template text. It installs the strings.Title function and uses it to Make Title Text Look Good In Our Template's Output.

Code:

// First create a struct to be validated
// according to the validator tags.
type ValidateExample struct {
    Name        string `validate:"nonzero"`
    Description string
    Age         int    `validate:"min=18"`
    Email       string `validate:"regexp=^[0-9a-z]+@[0-9a-z]+(\\.[0-9a-z]+)+$"`
    Address     struct {
        Street string `validate:"nonzero"`
        City   string `validate:"nonzero"`
    }
}

// Fill in some values
ve := ValidateExample{
    Name:        "Joe Doe", // valid as it's nonzero
    Description: "",        // valid no validation tag exists
    Age:         17,        // invalid as age is less than required 18
}
// invalid as Email won't match the regular expression
ve.Email = "@not.a.valid.email"
ve.Address.City = "Some City" // valid
ve.Address.Street = ""        // invalid

err := validator.Validate(ve)
if err == nil {
    fmt.Println("Values are valid.")
} else {
    errs := err.(validator.ErrorMap)
    // See if Address was empty
    if errs["Address.Street"][0] == validator.ErrZeroValue {
        fmt.Println("Street cannot be empty.")
    }

    // Iterate through the list of fields and respective errors
    fmt.Println("Invalid due to fields:")

    // Here we have to sort the arrays to ensure map ordering does not
    // fail our example, typically it's ok to just range through the err
    // list when order is not important.
    var errOuts []string
    for f, e := range errs {
        errOuts = append(errOuts, fmt.Sprintf("\t - %s (%v)\n", f, e))
    }

    // Again this part is extraneous and you should not need this in real
    // code.
    sort.Strings(errOuts)
    for _, str := range errOuts {
        fmt.Print(str)
    }
}

Output:

Street cannot be empty.
Invalid due to fields:
	 - Address.Street (zero value)
	 - Age (less than min)
	 - Email (regular expression mismatch)

type ErrorArray Uses

type ErrorArray []error

ErrorArray is a slice of errors returned by the Validate function.

func (ErrorArray) Error Uses

func (err ErrorArray) Error() string

ErrorArray implements the Error interface and returns the first error as string if existent.

type ErrorMap Uses

type ErrorMap map[string]ErrorArray

ErrorMap is a map which contains all errors from validating a struct.

func (ErrorMap) Error Uses

func (err ErrorMap) Error() string

ErrorMap implements the Error interface so we can check error against nil. The returned error is if existent the first error which was added to the map.

type TextErr Uses

type TextErr struct {
    Err error
}

TextErr is an error that also implements the TextMarshaller interface for serializing out to various plain text encodings. Packages creating their own custom errors should use TextErr if they're intending to use serializing formats like json, msgpack etc.

func (TextErr) Error Uses

func (t TextErr) Error() string

Error implements the error interface.

func (TextErr) MarshalText Uses

func (t TextErr) MarshalText() ([]byte, error)

MarshalText implements the TextMarshaller

type ValidationFunc Uses

type ValidationFunc func(v interface{}, param string) error

ValidationFunc is a function that receives the value of a field and a parameter used for the respective validation tag.

type Validator Uses

type Validator struct {
    // contains filtered or unexported fields
}

Validator implements a validator

func NewValidator Uses

func NewValidator() *Validator

NewValidator creates a new Validator

func WithTag Uses

func WithTag(tag string) *Validator

WithTag creates a new Validator with the new tag name. It is useful to chain-call with Validate so we don't change the tag name permanently: validator.WithTag("foo").Validate(t)

This example shows you how to change the tag name

Code:

type T struct {
    A int `foo:"nonzero" bar:"min=10"`
}
t := T{5}
err := validator.WithTag("foo").Validate(t)
fmt.Printf("foo --> valid: %v, errs: %v\n", err == nil, err)
err = validator.WithTag("bar").Validate(t)
fmt.Printf("bar --> valid: %v, errs: %v\n", err == nil, err)

Output:

foo --> valid: true, errs: <nil>
bar --> valid: false, errs: A: less than min

func (*Validator) SetTag Uses

func (mv *Validator) SetTag(tag string)

SetTag allows you to change the tag name used in structs

func (*Validator) SetValidationFunc Uses

func (mv *Validator) SetValidationFunc(name string, vf ValidationFunc) error

SetValidationFunc sets the function to be used for a given validation constraint. Calling this function with nil vf is the same as removing the constraint function from the list.

func (*Validator) Valid Uses

func (mv *Validator) Valid(val interface{}, tags string) error

Valid validates a value based on the provided tags and returns errors found or nil.

func (*Validator) Validate Uses

func (mv *Validator) Validate(v interface{}) error

Validate validates the fields of a struct based on 'validator' tags and returns errors found indexed by the field name.

func (*Validator) WithTag Uses

func (mv *Validator) WithTag(tag string) *Validator

WithTag creates a new Validator with the new tag name. It is useful to chain-call with Validate so we don't change the tag name permanently: validator.WithTag("foo").Validate(t)

Package validator imports 7 packages (graph) and is imported by 195 packages. Updated 2017-08-15. Refresh now. Tools for package owners.