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 245 package(s)

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

Imported only in test by 29 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/gokits/validator
  12. github.com/kefu1024/validator.v2
  13. github.com/keymastervn/validator
  14. github.com/leeprovoost/validator
  15. github.com/levenlabs/postmaster/db
  16. github.com/levenlabs/validator
  17. github.com/m3db/m3metrics/rules/validator/namespace/kv
  18. github.com/noaway/validator
  19. github.com/orangesquirrel/bond/models
  20. github.com/orangesquirrel/customer/models
  21. github.com/seedboxtech/validator
  22. github.com/syreclabs/validator
  23. github.com/vincentcr/validator
  24. github.com/vsheffer/validator
  25. github.com/xiqingping/validator
  26. github.com/zippoxer/validator
  27. gopkg.in/go-validator/validator.v2
  28. gopkg.in/noaway/validator.v1
  29. gopkg.uberinternal.com/validator.v2

Test imports 1 package(s)

  1. gopkg.in/check.v1