top

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().

Imported by 199 package(s)

  1. github.com/DaveBlooman/apex/function
  2. github.com/DaveBlooman/apex/project
  3. github.com/Efruit/marqit/market/v1
  4. github.com/Lanzafame/apex/function
  5. github.com/Lanzafame/apex/project
  6. github.com/LastZactionHero/contact_us/endpoints
  7. github.com/LevenLabs/dank/http
  8. github.com/LevenLabs/dank/types
  9. github.com/LevenLabs/go-typeform/tyform
  10. github.com/LevenLabs/golib/rpcutil
  11. github.com/LevenLabs/postmaster/sender
  12. github.com/LevenLabs/postmaster/webhook
  13. github.com/MrToy/business
  14. github.com/QuentinPerez/apex/function
  15. github.com/QuentinPerez/apex/project
  16. github.com/RiftBit/ALS-Go
  17. github.com/RiftBit/ALS-Go/httpmodels
  18. github.com/Riftbit/ALS-Go/httpmodels
  19. github.com/Skarlso/apex/function
  20. github.com/Skarlso/apex/project
  21. github.com/StreamRail/go-bqstreamer
  22. github.com/abhiyerra/apex/function
  23. github.com/abhiyerra/apex/project
  24. github.com/apex/apex/function
  25. github.com/apex/apex/project
  26. github.com/bearded-web/bearded/services
  27. github.com/bearded-web/bearded/services/issue
  28. github.com/bearded-web/bearded/services/target
  29. github.com/bearded-web/bearded/services/token
  30. github.com/cedmundo/hablo/api/friends
  31. github.com/cedmundo/hablo/api/groups
  32. github.com/cedmundo/hablo/api/profiles
  33. github.com/cedmundo/hablo/api/sessions
  34. github.com/cedmundo/hablo/models
  35. github.com/cloudfoundry-incubator/cf-mysql-benchmark-app/config
  36. github.com/cloudfoundry-incubator/cf-mysql-bootstrap/config
  37. github.com/cloudfoundry-incubator/galera-healthcheck/config
  38. github.com/cloudfoundry-incubator/switchboard/config
  39. github.com/cloudfoundry/mariadb_ctrl/config
  40. github.com/coderhaoxin/apex/function
  41. github.com/coderhaoxin/apex/project
  42. github.com/coopernurse/apex/function
  43. github.com/coopernurse/apex/project
  44. github.com/cubicdaiya/fuji/broker
  45. github.com/cubicdaiya/fuji/device
  46. github.com/cubicdaiya/fuji/gateway
  47. github.com/cubicdaiya/fuji/message
  48. github.com/dalvaren/gervice
  49. github.com/dcu/apex/function
  50. github.com/dcu/apex/project
  51. github.com/doomsplayer/apex/function
  52. github.com/doomsplayer/apex/project
  53. github.com/edoardo849/apex/function
  54. github.com/edoardo849/apex/project
  55. github.com/elizar/apex/function
  56. github.com/elizar/apex/project
  57. github.com/exu/go-workshops/670-libs-validator
  58. github.com/farazfazli/apex/function
  59. github.com/farazfazli/apex/project
  60. github.com/fernandezvara/go-bqstreamer
  61. github.com/fibo/apex/function
  62. github.com/fibo/apex/project
  63. github.com/gedex/simdoc/pkg/handler
  64. github.com/gedex/simdoc/pkg/model
  65. github.com/gitmonster/cmnodes/nodes
  66. github.com/gogap/valid
  67. github.com/gotokatsuya/apex/function
  68. github.com/gotokatsuya/apex/project
  69. github.com/grunmax/GinRedisApi/ctrl
  70. github.com/grunmax/ginredisapi/ctrl
  71. github.com/guregu/go-bqstreamer
  72. github.com/heridev/gophergala_repositories/vebomm
  73. github.com/ifraixedes/go-config
  74. github.com/iolloyd/apex/function
  75. github.com/iolloyd/apex/project
  76. github.com/itsyouonline/identityserver/clients/go/itsyouonline
  77. github.com/itsyouonline/identityserver/db/registry
  78. github.com/iwanbk/go-raml/tutorial/server
  79. github.com/jinuljt/goformvalidator
  80. github.com/jmcfarlane/apex/function
  81. github.com/jmcfarlane/apex/project
  82. github.com/johannesboyne/apex/function
  83. github.com/johannesboyne/apex/project
  84. github.com/jonathanmarvens/apex/function
  85. github.com/jonathanmarvens/apex/project
  86. github.com/kapilt/apex/function
  87. github.com/kapilt/apex/project
  88. github.com/karolhor/go-workshops/670-libs-validator
  89. github.com/keymastervn/http_lightweight
  90. github.com/kgbu/fuji/broker
  91. github.com/kgbu/fuji/device
  92. github.com/kgbu/fuji/gateway
  93. github.com/kgbu/fuji/message
  94. github.com/kiwih/heyfyi/heyfyiserver/account
  95. github.com/kkimu/martini-test
  96. github.com/kujohn/apex/function
  97. github.com/kujohn/apex/project
  98. github.com/kykl/go-bqstreamer
  99. github.com/kylehq/apex/function
  100. github.com/kylehq/apex/project
  101. github.com/lc0/apex/function
  102. github.com/lc0/apex/project
  103. github.com/levenlabs/dank/http
  104. github.com/levenlabs/dank/types
  105. github.com/levenlabs/go-typeform/tyform
  106. github.com/levenlabs/golib/rpcutil
  107. github.com/levenlabs/postmaster/sender
  108. github.com/levenlabs/postmaster/webhook
  109. github.com/lukaszbudnik/migrator/config
  110. github.com/magicshui/apex/function
  111. github.com/magicshui/apex/project
  112. github.com/mattdotmatt/bigstar/handlers
  113. github.com/mattdotmatt/moodicle/handlers
  114. github.com/mezzato/fuji/broker
  115. github.com/mezzato/fuji/device
  116. github.com/mezzato/fuji/gateway
  117. github.com/mezzato/fuji/message
  118. github.com/mingderwang/apex/function
  119. github.com/mingderwang/apex/project
  120. github.com/mitre/ecqm/controllers
  121. github.com/mooyoul/apex/function
  122. github.com/mooyoul/apex/project
  123. github.com/mpdroog/invoiced/rules
  124. github.com/mpdroog/rootdev-home
  125. github.com/mthenw/apex/function
  126. github.com/mthenw/apex/project
  127. github.com/mururu/fuji/broker
  128. github.com/mururu/fuji/device
  129. github.com/mururu/fuji/gateway
  130. github.com/mururu/fuji/message
  131. github.com/nightlyone/go-bqstreamer
  132. github.com/nmcclain/apex/function
  133. github.com/nmcclain/apex/project
  134. github.com/orangesquirrel/bond/controllers
  135. github.com/orangesquirrel/contract/controllers
  136. github.com/orangesquirrel/customer/controllers
  137. github.com/orangesquirrel/premium/controllers
  138. github.com/peiwenhu/auth/auth
  139. github.com/pilwon/apex/function
  140. github.com/pilwon/apex/project
  141. github.com/pivotal-cf-experimental/cf-mysql-quota-enforcer/config
  142. github.com/pivotal-cf-experimental/switchboard/config
  143. github.com/plutov/fo-rest/api
  144. github.com/polds/apex/function
  145. github.com/polds/apex/project
  146. github.com/raff/apex/function
  147. github.com/raff/apex/project
  148. github.com/ramitsurana/apex/function
  149. github.com/ramitsurana/apex/project
  150. github.com/robvanmieghem/go-raml/tutorial/server
  151. github.com/robzienert/apex/function
  152. github.com/robzienert/apex/project
  153. github.com/roger2000hk/apex/function
  154. github.com/roger2000hk/apex/project
  155. github.com/roth1002/apex/function
  156. github.com/roth1002/apex/project
  157. github.com/segmentio/objects-go
  158. github.com/shiguredo/fuji/broker
  159. github.com/shiguredo/fuji/device
  160. github.com/shiguredo/fuji/gateway
  161. github.com/shiguredo/fuji/message
  162. github.com/shirou/fuji/broker
  163. github.com/shirou/fuji/device
  164. github.com/shirou/fuji/gateway
  165. github.com/shirou/fuji/message
  166. github.com/skarlso/apex/function
  167. github.com/skarlso/apex/project
  168. github.com/slantin/np-compiler/config
  169. github.com/slantin/np-compiler/soundcloud
  170. github.com/sohlich/go-plag
  171. github.com/sohlich/survey_kiosk/domain
  172. github.com/songofhack/bearded/services
  173. github.com/sontags/go-raml/tutorial/server
  174. github.com/stancarney/gowork
  175. github.com/streamrail/go-bqstreamer
  176. github.com/takasing/golang-gin-api/model
  177. github.com/takasing/golang-webapp/model
  178. github.com/tj/go-config
  179. github.com/tmtk75/apex/function
  180. github.com/tmtk75/apex/project
  181. github.com/typerandom/validator/bench
  182. github.com/veqryn/apex/function
  183. github.com/veqryn/apex/project
  184. github.com/victorquinn/apex/function
  185. github.com/victorquinn/apex/project
  186. github.com/vincentcr/huecontrol/api
  187. github.com/vsheffer/docker/mongo/mongo-config/pkg
  188. github.com/vsheffer/go-swagger-codegen/model
  189. github.com/vsukhin/RESTfulAPI/models
  190. github.com/wolfeidau/apex/function
  191. github.com/wolfeidau/apex/project
  192. github.com/wujiang/apex/function
  193. github.com/wujiang/apex/project
  194. github.com/yosukesuzuki/bell-app-review-notify
  195. github.com/yudppp/go-config
  196. github.com/zamN/zounce/config
  197. github.com/zamN/zounce/config/confutils
  198. gopkg.in/rounds/go-bqstreamer.v1
  199. gopkg.in/typerandom/validator.v0/bench

Imported only in test by 25 package(s)

  1. github.com/CrowdSurge/validator
  2. github.com/LevenLabs/postmaster/db
  3. github.com/LevenLabs/validator
  4. github.com/Pitmairen/validator
  5. github.com/THE108/validator
  6. github.com/crowdsurge/validator
  7. github.com/denkhaus/validator
  8. github.com/gin-gonic/validator
  9. github.com/go-validator/validator
  10. github.com/goburrow/validator
  11. github.com/kefu1024/validator.v2
  12. github.com/keymastervn/validator
  13. github.com/leeprovoost/validator
  14. github.com/levenlabs/postmaster/db
  15. github.com/levenlabs/validator
  16. github.com/orangesquirrel/bond/models
  17. github.com/orangesquirrel/customer/models
  18. github.com/syreclabs/validator
  19. github.com/vincentcr/validator
  20. github.com/vsheffer/validator
  21. github.com/xiqingping/validator
  22. github.com/zippoxer/validator
  23. gopkg.in/go-validator/validator.v2
  24. gopkg.in/noaway/validator.v1
  25. gopkg.uberinternal.com/validator.v2

Test imports 1 package(s)

  1. gopkg.in/check.v1