Categorygithub.com/marksalpeter/validator
modulepackage
0.1.2
Repository: https://github.com/marksalpeter/validator.git
Documentation: pkg.go.dev

# README

GoDoc

This is a validation package for golang that returns human readable error messages. Its ideal for validating input data for public facing restful api's.

It has the following features

  • Combination of validators with logical operators (e.g. &, |, ())
  • Cross field and cross struct validation (e.g. firstName and lastName must be set)
  • Custom validators, e.g. validator.AddRule("name", func(ps..) error)
  • Customizable i18n aware error messages using the golang.org/x/text/message package

How it works

Validator uses struct tags to verify data passed in to apis. Use the validate tag to apply various Rules that the field must follow (e.g. validate:"email"). You can add custom validation rules as necessary by implementing your own validator.Rule functions. This package also comes with several common rules referenced below such as number:min,max, email, password, etc.

Example

package main

import "github.com/marksalpeter/validator"

type User struct {
	FirstName    string `json:"firstName,omitempty" validate:"name"`           // FirstName cannot contain numbers or special characters
	LastName     string `json:"lastName,omitempty" validate:"name"`            // LastName cannot contain numbers or special characters
	EmailAddress string `json:"emailAddress,omitempty" validate:"email"`       // EmailAddress must be a valid email address
	PhoneNumber  string `json:"phoneNumber,omitempty" validate:"number:11,15"` // PhoneNumber must be 11-15 numbers e.g 15551234567
}

func main() {

	// displays all validation errors
	var user User
	v := validator.New()
	if err := v.Validate(&user); err != nil {
		fmt.Println(err) // prints ["'firstName' must be a valid name","'lastName' must be a valid name","'emailAddress' must be a valid email address","'phoneNumber' must contain only numbers"]
	}

	// set the properties
	user.FirstName = "First"
	user.LastName = "Last"
	user.EmailAddress = "[email protected]"
	user.PhoneNumber = "15551234567"
	if err := v.Validate(); err != nil {
		panic(err)
	}
	fmt.Println("user data is valid!")
}

Advanced Example

package main

import "github.com/marksalpeter/validator"

// User can either set name or firstName and lastName
type User struct {
	Name      string `json:"name,omitempty" validate:"name | or:FirstName,LastName"`
	FirstName string `json:"firstName,omitempty" validate:"empty | (name & and:LastName)"`
	LastName  string `json:"lastName,omitempty" validate:"empty | (name & and:FirstName)"`
}

func main() {

	var user User
	v := validator.New()

	// empty struct fails on `or:FirstName,LastName`
	if err := v.Validate(&user); err != nil {
		fmt.Println(err) // prints ["either 'name', 'firstName' and/or 'lastName' must be set"]
	}

	// only first name fails on `(name & and:LastName)`
	user.FirstName = "First"
	user.LastName = ""
	if err := v.Validate(&user); err != nil {
		fmt.Println(err) // prints ["'firstName' and 'lastName' must be set"]
	}

	// only last name fails on (name & and:FirstName)
	user.FirstName = ""
	user.LastName = "Last"
	if err := v.Validate(&user); err != nil {
		fmt.Println(err) // prints ["'lastName' and 'firstName' must be set"]
	}

	// first and last name are set first name passes
	user.FirstName = "First"
	user.LastName = "Last"
	if err := v.Validate(&user); err != nil {
		fmt.Println(err) // never reached
	}

	// name passes
	user.Name = "First Last"
	user.FirstName = ""
	user.LastName = ""
	if err := v.Validate(&user); err != nil {
		fmt.Println(err) // never reached
	}

}

Validation Rules

This package comes with several default validation rules:

RuleDescription
requiredrequired returns an error if the filed contains the zero value of the type or nil
emptyempty returns an error if the field is not empty
namename returns an error if the field doesn't contain a valid name
emailemail returns an error if the field doesn't contain a valid email address
passwordpassword returns an error if the field doesn't contain a valid password
numbernumber retuns an error if the field doesn't contain numbers only
lettersletters retuns an error if the field doesn't contain letters only
eqeq returns an error if the field does not == one of the params passed in
xorxor returns an error when more than one or zero of either the field that it is applied to or any of the field names passed as params are set to a non zero value
oror returns an error when neither the field that it is applied to nor any of the field names passed as params are set to a non zero value
andand returns an error when the field that it is applied to or any of the field names passed as params are set to the zero value

Required ^

Required returns an error if the filed contains the zero value of the type or nil.

Example

type Struct struct {
	Field  string `json:"field" validate:"required"` // 'field' is required
}

Empty ^

Empty returns an error if the field is not empty. It should be 'or'd together with other rules that require manditory input

Example

type Struct struct {
	Field  string `json:"field" validate:"empty | email"` // 'field' must be a valid email address or not set at all
}

Name ^

Name returns an error if the field doesn't contain a valid name i.e. no numbers or most special characters, excepting characters that may be in a name like a - and allowing foreign language letters with accent marks as well as spaces This prevents things like emails or phone numbers from being entered as a name.

Example

type Struct struct {
	Field  string `json:"field" validate:"name"` // 'field' must be a valid name
}

Email ^

Email returns an error if the field doesn't contain a valid email address

Example

type Struct struct {
	Field  string `json:"field" validate:"email"` // 'field' must be a valid email address
}

Password ^

Password returns an error if the field doesn't contain a valid password

Example

type Struct struct {
	Field  string `json:"field" validate:"password"` // 'field' must be a valid password
}

Number ^

Number retuns an error if the field doesn't contain numbers only

Example

type Struct struct {
	Field   string `json:"field" validate:"number"`      // 'field' must contain only numbers
	Field2  string `json:"field2" validate:"number:3,5"` // 'field2' must be 3 to 5 digits
	Field3  uint   `json:"field3" validate:"number:3,5"` // 'field3' must be 3 to 5
}

Letters ^

Letters retuns an error if the field doesn't contain letters only

Example

type Struct struct {
	Field  string `json:"field" validate:"letters"` // 'field' can only take letters and spaces
}

EQ ^

EQ returns an error if the field does not == one of the params passed in

Example

type Struct struct {
	Field  string `json:"field" validate:"eq:one,two,three"` // 'field' must equal either "one", "two", or "three"
}

XOR ^

XOR returns an error when more than one or zero of either the field that it is applied to or any of the field names passed as params are set to a non zero value

Example

type Struct struct {
	Field  string `json:"field" validate:" xor:Field2"` // either "field" or "Field2" must be set
	Field2 string
}

OR ^

OR returns an error when neither the field that it is applied to nor any of the field names passed as params are set to a non zero value

Example

type Struct struct {
	Field  string `json:"field" validate:"or:Field2"` // either "field" or "Field2" or both must be set
	Field2 string
}

AND ^

AND returns an error when the field that it is applied to or any of the field names passed as params are set to the zero value

Example

type Struct struct {
	Field  string `json:"field" validate:"and:Field2"` // "field" and "Field2" must be set
	Field2 string
}

Special Mentions

This package was heavily inspired by the go-playground validator and was originally envisioned as a more flexible, powerful version of the same basic concept.

How to Contribute

Open a pull request 😁

License

Distributed under MIT License, please see license file within the code for more details.

# Functions

AddRule adds a rule to the `DefaultRules`.
AND returns an error when the field that it is applied to or any of the field names passed as params are set to the zero value Example type Struct struct { Field string `json:"field" validate:"and:Field2"` // "field" and "Field2" must be set Field2 string } .
CheckSyntax cycles though all of the validation tags and returns bad syntax errors instead of panicing.
Email returns an error if the field doesn't contain a valid email address Example type Struct struct { Field string `json:"field" validate:"email"` // 'field' must be a valid email address } .
Empty returns an error if the field is not empty.
EQ returns an error if the field does not == one of the params passed in Example type Struct struct { Field string `json:"field" validate:"eq:one,two,three"` // 'field' must equal either "one", "two", or "three" } .
Letters retuns an error if the field doesn't contain letters only Example type Struct struct { Field string `json:"field" validate:"letters"` // 'field' can only take letters and spaces } .
Name returns an error if the field doesn't contain a valid name I.e.
New returns a new Validator It will parse the validation tags in the following fashion: Example type Example struct { Field string `validator:"one | (two & three)"` } New().Validate(&Example{}) The field will be deemed valid if one(Example.Field) == nil || (two(Example.Field) == nil && three(Example.Field) == nil) .
Number retuns an error if the field doesn't contain numbers only Example type Struct struct { Field string `json:"field" validate:"number"` // 'field' must contain only numbers Field2 string `json:"field2" validate:"number:3,5"` // 'field2' must be 3 to 5 digits Field3 uint `json:"field3" validate:"number:3,5"` // 'field3' must be 3 to 5 } .
OR returns an error when neither the field that it is applied to nor any of the field names passed as params are set to a non zero value Example type Struct struct { Field string `json:"field" validate:"or:Field2"` // either "field" or "Field2" or both must be set Field2 string } .
Password returns an error if the field doesn't contain a valid password Example type Struct struct { Field string `json:"field" validate:"password"` // 'field' must be a valid password } .
Required returns an error if the filed contains the zero value of the type or nil.
Validate validates a struct or a slice based on the information passed to the 'validate' tag.
XOR returns an error when more than one or zero of either the field that it is applied to or any of the field names passed as params are set to a non zero value Example type Struct struct { Field string `json:"field" validate:" xor:Field2"` // either "field" or "Field2" must be set Field2 string } .

# Constants

DefaultTag is the tage used if Config.Tag is not set.

# Variables

DefaultRules is the default set of rules the validator will be created with.
DefaultValidator is the default validator used by the `Validate` and `CheckSyntax` funcs.

# Structs

Config configures the validator.
FieldError is the error returned when a field rule returns an error.
RuleParams is the set of parameters a rule processes to determine if there was a validation error.

# Interfaces

Errors contains a slice of errors.
Validator validates structs and slices.

# Type aliases

FieldErrors are slice of FieldError generate by the rules.
Rule is a rule that is applied to a field in a struct.
Rules are a set of rules that the `Validator` will look up by name in order to appy them to fields in a struct.