You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

616 lines
24 KiB

  1. govalidator
  2. ===========
  3. [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) [![Coverage Status](https://img.shields.io/coveralls/asaskevich/govalidator.svg)](https://coveralls.io/r/asaskevich/govalidator?branch=master) [![wercker status](https://app.wercker.com/status/1ec990b09ea86c910d5f08b0e02c6043/s "wercker status")](https://app.wercker.com/project/bykey/1ec990b09ea86c910d5f08b0e02c6043)
  4. [![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield)
  5. A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js).
  6. #### Installation
  7. Make sure that Go is installed on your computer.
  8. Type the following command in your terminal:
  9. go get github.com/asaskevich/govalidator
  10. or you can get specified release of the package with `gopkg.in`:
  11. go get gopkg.in/asaskevich/govalidator.v10
  12. After it the package is ready to use.
  13. #### Import package in your project
  14. Add following line in your `*.go` file:
  15. ```go
  16. import "github.com/asaskevich/govalidator"
  17. ```
  18. If you are unhappy to use long `govalidator`, you can do something like this:
  19. ```go
  20. import (
  21. valid "github.com/asaskevich/govalidator"
  22. )
  23. ```
  24. #### Activate behavior to require all fields have a validation tag by default
  25. `SetFieldsRequiredByDefault` causes validation to fail when struct fields do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). A good place to activate this is a package init function or the main() function.
  26. `SetNilPtrAllowedByRequired` causes validation to pass when struct fields marked by `required` are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between `nil` and `zero value` state can use this. If disabled, both `nil` and `zero` values cause validation errors.
  27. ```go
  28. import "github.com/asaskevich/govalidator"
  29. func init() {
  30. govalidator.SetFieldsRequiredByDefault(true)
  31. }
  32. ```
  33. Here's some code to explain it:
  34. ```go
  35. // this struct definition will fail govalidator.ValidateStruct() (and the field values do not matter):
  36. type exampleStruct struct {
  37. Name string ``
  38. Email string `valid:"email"`
  39. }
  40. // this, however, will only fail when Email is empty or an invalid email address:
  41. type exampleStruct2 struct {
  42. Name string `valid:"-"`
  43. Email string `valid:"email"`
  44. }
  45. // lastly, this will only fail when Email is an invalid email address but not when it's empty:
  46. type exampleStruct2 struct {
  47. Name string `valid:"-"`
  48. Email string `valid:"email,optional"`
  49. }
  50. ```
  51. #### Recent breaking changes (see [#123](https://github.com/asaskevich/govalidator/pull/123))
  52. ##### Custom validator function signature
  53. A context was added as the second parameter, for structs this is the object being validated – this makes dependent validation possible.
  54. ```go
  55. import "github.com/asaskevich/govalidator"
  56. // old signature
  57. func(i interface{}) bool
  58. // new signature
  59. func(i interface{}, o interface{}) bool
  60. ```
  61. ##### Adding a custom validator
  62. This was changed to prevent data races when accessing custom validators.
  63. ```go
  64. import "github.com/asaskevich/govalidator"
  65. // before
  66. govalidator.CustomTypeTagMap["customByteArrayValidator"] = func(i interface{}, o interface{}) bool {
  67. // ...
  68. }
  69. // after
  70. govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, o interface{}) bool {
  71. // ...
  72. })
  73. ```
  74. #### List of functions:
  75. ```go
  76. func Abs(value float64) float64
  77. func BlackList(str, chars string) string
  78. func ByteLength(str string, params ...string) bool
  79. func CamelCaseToUnderscore(str string) string
  80. func Contains(str, substring string) bool
  81. func Count(array []interface{}, iterator ConditionIterator) int
  82. func Each(array []interface{}, iterator Iterator)
  83. func ErrorByField(e error, field string) string
  84. func ErrorsByField(e error) map[string]string
  85. func Filter(array []interface{}, iterator ConditionIterator) []interface{}
  86. func Find(array []interface{}, iterator ConditionIterator) interface{}
  87. func GetLine(s string, index int) (string, error)
  88. func GetLines(s string) []string
  89. func HasLowerCase(str string) bool
  90. func HasUpperCase(str string) bool
  91. func HasWhitespace(str string) bool
  92. func HasWhitespaceOnly(str string) bool
  93. func InRange(value interface{}, left interface{}, right interface{}) bool
  94. func InRangeFloat32(value, left, right float32) bool
  95. func InRangeFloat64(value, left, right float64) bool
  96. func InRangeInt(value, left, right interface{}) bool
  97. func IsASCII(str string) bool
  98. func IsAlpha(str string) bool
  99. func IsAlphanumeric(str string) bool
  100. func IsBase64(str string) bool
  101. func IsByteLength(str string, min, max int) bool
  102. func IsCIDR(str string) bool
  103. func IsCRC32(str string) bool
  104. func IsCRC32b(str string) bool
  105. func IsCreditCard(str string) bool
  106. func IsDNSName(str string) bool
  107. func IsDataURI(str string) bool
  108. func IsDialString(str string) bool
  109. func IsDivisibleBy(str, num string) bool
  110. func IsEmail(str string) bool
  111. func IsExistingEmail(email string) bool
  112. func IsFilePath(str string) (bool, int)
  113. func IsFloat(str string) bool
  114. func IsFullWidth(str string) bool
  115. func IsHalfWidth(str string) bool
  116. func IsHash(str string, algorithm string) bool
  117. func IsHexadecimal(str string) bool
  118. func IsHexcolor(str string) bool
  119. func IsHost(str string) bool
  120. func IsIP(str string) bool
  121. func IsIPv4(str string) bool
  122. func IsIPv6(str string) bool
  123. func IsISBN(str string, version int) bool
  124. func IsISBN10(str string) bool
  125. func IsISBN13(str string) bool
  126. func IsISO3166Alpha2(str string) bool
  127. func IsISO3166Alpha3(str string) bool
  128. func IsISO4217(str string) bool
  129. func IsISO693Alpha2(str string) bool
  130. func IsISO693Alpha3b(str string) bool
  131. func IsIn(str string, params ...string) bool
  132. func IsInRaw(str string, params ...string) bool
  133. func IsInt(str string) bool
  134. func IsJSON(str string) bool
  135. func IsLatitude(str string) bool
  136. func IsLongitude(str string) bool
  137. func IsLowerCase(str string) bool
  138. func IsMAC(str string) bool
  139. func IsMD4(str string) bool
  140. func IsMD5(str string) bool
  141. func IsMagnetURI(str string) bool
  142. func IsMongoID(str string) bool
  143. func IsMultibyte(str string) bool
  144. func IsNatural(value float64) bool
  145. func IsNegative(value float64) bool
  146. func IsNonNegative(value float64) bool
  147. func IsNonPositive(value float64) bool
  148. func IsNotNull(str string) bool
  149. func IsNull(str string) bool
  150. func IsNumeric(str string) bool
  151. func IsPort(str string) bool
  152. func IsPositive(value float64) bool
  153. func IsPrintableASCII(str string) bool
  154. func IsRFC3339(str string) bool
  155. func IsRFC3339WithoutZone(str string) bool
  156. func IsRGBcolor(str string) bool
  157. func IsRequestURI(rawurl string) bool
  158. func IsRequestURL(rawurl string) bool
  159. func IsRipeMD128(str string) bool
  160. func IsRipeMD160(str string) bool
  161. func IsRsaPub(str string, params ...string) bool
  162. func IsRsaPublicKey(str string, keylen int) bool
  163. func IsSHA1(str string) bool
  164. func IsSHA256(str string) bool
  165. func IsSHA384(str string) bool
  166. func IsSHA512(str string) bool
  167. func IsSSN(str string) bool
  168. func IsSemver(str string) bool
  169. func IsTiger128(str string) bool
  170. func IsTiger160(str string) bool
  171. func IsTiger192(str string) bool
  172. func IsTime(str string, format string) bool
  173. func IsType(v interface{}, params ...string) bool
  174. func IsURL(str string) bool
  175. func IsUTFDigit(str string) bool
  176. func IsUTFLetter(str string) bool
  177. func IsUTFLetterNumeric(str string) bool
  178. func IsUTFNumeric(str string) bool
  179. func IsUUID(str string) bool
  180. func IsUUIDv3(str string) bool
  181. func IsUUIDv4(str string) bool
  182. func IsUUIDv5(str string) bool
  183. func IsUnixTime(str string) bool
  184. func IsUpperCase(str string) bool
  185. func IsVariableWidth(str string) bool
  186. func IsWhole(value float64) bool
  187. func LeftTrim(str, chars string) string
  188. func Map(array []interface{}, iterator ResultIterator) []interface{}
  189. func Matches(str, pattern string) bool
  190. func MaxStringLength(str string, params ...string) bool
  191. func MinStringLength(str string, params ...string) bool
  192. func NormalizeEmail(str string) (string, error)
  193. func PadBoth(str string, padStr string, padLen int) string
  194. func PadLeft(str string, padStr string, padLen int) string
  195. func PadRight(str string, padStr string, padLen int) string
  196. func PrependPathToErrors(err error, path string) error
  197. func Range(str string, params ...string) bool
  198. func RemoveTags(s string) string
  199. func ReplacePattern(str, pattern, replace string) string
  200. func Reverse(s string) string
  201. func RightTrim(str, chars string) string
  202. func RuneLength(str string, params ...string) bool
  203. func SafeFileName(str string) string
  204. func SetFieldsRequiredByDefault(value bool)
  205. func SetNilPtrAllowedByRequired(value bool)
  206. func Sign(value float64) float64
  207. func StringLength(str string, params ...string) bool
  208. func StringMatches(s string, params ...string) bool
  209. func StripLow(str string, keepNewLines bool) string
  210. func ToBoolean(str string) (bool, error)
  211. func ToFloat(str string) (float64, error)
  212. func ToInt(value interface{}) (res int64, err error)
  213. func ToJSON(obj interface{}) (string, error)
  214. func ToString(obj interface{}) string
  215. func Trim(str, chars string) string
  216. func Truncate(str string, length int, ending string) string
  217. func TruncatingErrorf(str string, args ...interface{}) error
  218. func UnderscoreToCamelCase(s string) string
  219. func ValidateMap(inputMap map[string]interface{}, validationMap map[string]interface{}) (bool, error)
  220. func ValidateStruct(s interface{}) (bool, error)
  221. func WhiteList(str, chars string) string
  222. type ConditionIterator
  223. type CustomTypeValidator
  224. type Error
  225. func (e Error) Error() string
  226. type Errors
  227. func (es Errors) Error() string
  228. func (es Errors) Errors() []error
  229. type ISO3166Entry
  230. type ISO693Entry
  231. type InterfaceParamValidator
  232. type Iterator
  233. type ParamValidator
  234. type ResultIterator
  235. type UnsupportedTypeError
  236. func (e *UnsupportedTypeError) Error() string
  237. type Validator
  238. ```
  239. #### Examples
  240. ###### IsURL
  241. ```go
  242. println(govalidator.IsURL(`http://user@pass:domain.com/path/page`))
  243. ```
  244. ###### IsType
  245. ```go
  246. println(govalidator.IsType("Bob", "string"))
  247. println(govalidator.IsType(1, "int"))
  248. i := 1
  249. println(govalidator.IsType(&i, "*int"))
  250. ```
  251. IsType can be used through the tag `type` which is essential for map validation:
  252. ```go
  253. type User struct {
  254. Name string `valid:"type(string)"`
  255. Age int `valid:"type(int)"`
  256. Meta interface{} `valid:"type(string)"`
  257. }
  258. result, err := govalidator.ValidateStruct(user{"Bob", 20, "meta"})
  259. if err != nil {
  260. println("error: " + err.Error())
  261. }
  262. println(result)
  263. ```
  264. ###### ToString
  265. ```go
  266. type User struct {
  267. FirstName string
  268. LastName string
  269. }
  270. str := govalidator.ToString(&User{"John", "Juan"})
  271. println(str)
  272. ```
  273. ###### Each, Map, Filter, Count for slices
  274. Each iterates over the slice/array and calls Iterator for every item
  275. ```go
  276. data := []interface{}{1, 2, 3, 4, 5}
  277. var fn govalidator.Iterator = func(value interface{}, index int) {
  278. println(value.(int))
  279. }
  280. govalidator.Each(data, fn)
  281. ```
  282. ```go
  283. data := []interface{}{1, 2, 3, 4, 5}
  284. var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} {
  285. return value.(int) * 3
  286. }
  287. _ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15}
  288. ```
  289. ```go
  290. data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  291. var fn govalidator.ConditionIterator = func(value interface{}, index int) bool {
  292. return value.(int)%2 == 0
  293. }
  294. _ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10}
  295. _ = govalidator.Count(data, fn) // result = 5
  296. ```
  297. ###### ValidateStruct [#2](https://github.com/asaskevich/govalidator/pull/2)
  298. If you want to validate structs, you can use tag `valid` for any field in your structure. All validators used with this field in one tag are separated by comma. If you want to skip validation, place `-` in your tag. If you need a validator that is not on the list below, you can add it like this:
  299. ```go
  300. govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
  301. return str == "duck"
  302. })
  303. ```
  304. For completely custom validators (interface-based), see below.
  305. Here is a list of available validators for struct fields (validator - used function):
  306. ```go
  307. "email": IsEmail,
  308. "url": IsURL,
  309. "dialstring": IsDialString,
  310. "requrl": IsRequestURL,
  311. "requri": IsRequestURI,
  312. "alpha": IsAlpha,
  313. "utfletter": IsUTFLetter,
  314. "alphanum": IsAlphanumeric,
  315. "utfletternum": IsUTFLetterNumeric,
  316. "numeric": IsNumeric,
  317. "utfnumeric": IsUTFNumeric,
  318. "utfdigit": IsUTFDigit,
  319. "hexadecimal": IsHexadecimal,
  320. "hexcolor": IsHexcolor,
  321. "rgbcolor": IsRGBcolor,
  322. "lowercase": IsLowerCase,
  323. "uppercase": IsUpperCase,
  324. "int": IsInt,
  325. "float": IsFloat,
  326. "null": IsNull,
  327. "uuid": IsUUID,
  328. "uuidv3": IsUUIDv3,
  329. "uuidv4": IsUUIDv4,
  330. "uuidv5": IsUUIDv5,
  331. "creditcard": IsCreditCard,
  332. "isbn10": IsISBN10,
  333. "isbn13": IsISBN13,
  334. "json": IsJSON,
  335. "multibyte": IsMultibyte,
  336. "ascii": IsASCII,
  337. "printableascii": IsPrintableASCII,
  338. "fullwidth": IsFullWidth,
  339. "halfwidth": IsHalfWidth,
  340. "variablewidth": IsVariableWidth,
  341. "base64": IsBase64,
  342. "datauri": IsDataURI,
  343. "ip": IsIP,
  344. "port": IsPort,
  345. "ipv4": IsIPv4,
  346. "ipv6": IsIPv6,
  347. "dns": IsDNSName,
  348. "host": IsHost,
  349. "mac": IsMAC,
  350. "latitude": IsLatitude,
  351. "longitude": IsLongitude,
  352. "ssn": IsSSN,
  353. "semver": IsSemver,
  354. "rfc3339": IsRFC3339,
  355. "rfc3339WithoutZone": IsRFC3339WithoutZone,
  356. "ISO3166Alpha2": IsISO3166Alpha2,
  357. "ISO3166Alpha3": IsISO3166Alpha3,
  358. ```
  359. Validators with parameters
  360. ```go
  361. "range(min|max)": Range,
  362. "length(min|max)": ByteLength,
  363. "runelength(min|max)": RuneLength,
  364. "stringlength(min|max)": StringLength,
  365. "matches(pattern)": StringMatches,
  366. "in(string1|string2|...|stringN)": IsIn,
  367. "rsapub(keylength)" : IsRsaPub,
  368. ```
  369. Validators with parameters for any type
  370. ```go
  371. "type(type)": IsType,
  372. ```
  373. And here is small example of usage:
  374. ```go
  375. type Post struct {
  376. Title string `valid:"alphanum,required"`
  377. Message string `valid:"duck,ascii"`
  378. Message2 string `valid:"animal(dog)"`
  379. AuthorIP string `valid:"ipv4"`
  380. Date string `valid:"-"`
  381. }
  382. post := &Post{
  383. Title: "My Example Post",
  384. Message: "duck",
  385. Message2: "dog",
  386. AuthorIP: "123.234.54.3",
  387. }
  388. // Add your own struct validation tags
  389. govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
  390. return str == "duck"
  391. })
  392. // Add your own struct validation tags with parameter
  393. govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool {
  394. species := params[0]
  395. return str == species
  396. })
  397. govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$")
  398. result, err := govalidator.ValidateStruct(post)
  399. if err != nil {
  400. println("error: " + err.Error())
  401. }
  402. println(result)
  403. ```
  404. ###### ValidateMap [#2](https://github.com/asaskevich/govalidator/pull/338)
  405. If you want to validate maps, you can use the map to be validated and a validation map that contain the same tags used in ValidateStruct, both maps have to be in the form `map[string]interface{}`
  406. So here is small example of usage:
  407. ```go
  408. var mapTemplate = map[string]interface{}{
  409. "name":"required,alpha",
  410. "family":"required,alpha",
  411. "email":"required,email",
  412. "cell-phone":"numeric",
  413. "address":map[string]interface{}{
  414. "line1":"required,alphanum",
  415. "line2":"alphanum",
  416. "postal-code":"numeric",
  417. },
  418. }
  419. var inputMap = map[string]interface{}{
  420. "name":"Bob",
  421. "family":"Smith",
  422. "email":"foo@bar.baz",
  423. "address":map[string]interface{}{
  424. "line1":"",
  425. "line2":"",
  426. "postal-code":"",
  427. },
  428. }
  429. result, err := govalidator.ValidateMap(inputMap, mapTemplate)
  430. if err != nil {
  431. println("error: " + err.Error())
  432. }
  433. println(result)
  434. ```
  435. ###### WhiteList
  436. ```go
  437. // Remove all characters from string ignoring characters between "a" and "z"
  438. println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa")
  439. ```
  440. ###### Custom validation functions
  441. Custom validation using your own domain specific validators is also available - here's an example of how to use it:
  442. ```go
  443. import "github.com/asaskevich/govalidator"
  444. type CustomByteArray [6]byte // custom types are supported and can be validated
  445. type StructWithCustomByteArray struct {
  446. ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // multiple custom validators are possible as well and will be evaluated in sequence
  447. Email string `valid:"email"`
  448. CustomMinLength int `valid:"-"`
  449. }
  450. govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, context interface{}) bool {
  451. switch v := context.(type) { // you can type switch on the context interface being validated
  452. case StructWithCustomByteArray:
  453. // you can check and validate against some other field in the context,
  454. // return early or not validate against the context at all – your choice
  455. case SomeOtherType:
  456. // ...
  457. default:
  458. // expecting some other type? Throw/panic here or continue
  459. }
  460. switch v := i.(type) { // type switch on the struct field being validated
  461. case CustomByteArray:
  462. for _, e := range v { // this validator checks that the byte array is not empty, i.e. not all zeroes
  463. if e != 0 {
  464. return true
  465. }
  466. }
  467. }
  468. return false
  469. })
  470. govalidator.CustomTypeTagMap.Set("customMinLengthValidator", func(i interface{}, context interface{}) bool {
  471. switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation
  472. case StructWithCustomByteArray:
  473. return len(v.ID) >= v.CustomMinLength
  474. }
  475. return false
  476. })
  477. ```
  478. ###### Loop over Error()
  479. By default .Error() returns all errors in a single String. To access each error you can do this:
  480. ```go
  481. if err != nil {
  482. errs := err.(govalidator.Errors).Errors()
  483. for _, e := range errs {
  484. fmt.Println(e.Error())
  485. }
  486. }
  487. ```
  488. ###### Custom error messages
  489. Custom error messages are supported via annotations by adding the `~` separator - here's an example of how to use it:
  490. ```go
  491. type Ticket struct {
  492. Id int64 `json:"id"`
  493. FirstName string `json:"firstname" valid:"required~First name is blank"`
  494. }
  495. ```
  496. #### Notes
  497. Documentation is available here: [godoc.org](https://godoc.org/github.com/asaskevich/govalidator).
  498. Full information about code coverage is also available here: [govalidator on gocover.io](http://gocover.io/github.com/asaskevich/govalidator).
  499. #### Support
  500. If you do have a contribution to the package, feel free to create a Pull Request or an Issue.
  501. #### What to contribute
  502. If you don't know what to do, there are some features and functions that need to be done
  503. - [ ] Refactor code
  504. - [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check
  505. - [ ] Create actual list of contributors and projects that currently using this package
  506. - [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues)
  507. - [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions)
  508. - [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new
  509. - [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc
  510. - [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
  511. - [ ] Implement fuzzing testing
  512. - [ ] Implement some struct/map/array utilities
  513. - [ ] Implement map/array validation
  514. - [ ] Implement benchmarking
  515. - [ ] Implement batch of examples
  516. - [ ] Look at forks for new features and fixes
  517. #### Advice
  518. Feel free to create what you want, but keep in mind when you implement new features:
  519. - Code must be clear and readable, names of variables/constants clearly describes what they are doing
  520. - Public functions must be documented and described in source file and added to README.md to the list of available functions
  521. - There are must be unit-tests for any new functions and improvements
  522. ## Credits
  523. ### Contributors
  524. This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
  525. #### Special thanks to [contributors](https://github.com/asaskevich/govalidator/graphs/contributors)
  526. * [Daniel Lohse](https://github.com/annismckenzie)
  527. * [Attila Oláh](https://github.com/attilaolah)
  528. * [Daniel Korner](https://github.com/Dadie)
  529. * [Steven Wilkin](https://github.com/stevenwilkin)
  530. * [Deiwin Sarjas](https://github.com/deiwin)
  531. * [Noah Shibley](https://github.com/slugmobile)
  532. * [Nathan Davies](https://github.com/nathj07)
  533. * [Matt Sanford](https://github.com/mzsanford)
  534. * [Simon ccl1115](https://github.com/ccl1115)
  535. <a href="https://github.com/asaskevich/govalidator/graphs/contributors"><img src="https://opencollective.com/govalidator/contributors.svg?width=890" /></a>
  536. ### Backers
  537. Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/govalidator#backer)]
  538. <a href="https://opencollective.com/govalidator#backers" target="_blank"><img src="https://opencollective.com/govalidator/backers.svg?width=890"></a>
  539. ### Sponsors
  540. Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/govalidator#sponsor)]
  541. <a href="https://opencollective.com/govalidator/sponsor/0/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/0/avatar.svg"></a>
  542. <a href="https://opencollective.com/govalidator/sponsor/1/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/1/avatar.svg"></a>
  543. <a href="https://opencollective.com/govalidator/sponsor/2/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/2/avatar.svg"></a>
  544. <a href="https://opencollective.com/govalidator/sponsor/3/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/3/avatar.svg"></a>
  545. <a href="https://opencollective.com/govalidator/sponsor/4/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/4/avatar.svg"></a>
  546. <a href="https://opencollective.com/govalidator/sponsor/5/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/5/avatar.svg"></a>
  547. <a href="https://opencollective.com/govalidator/sponsor/6/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/6/avatar.svg"></a>
  548. <a href="https://opencollective.com/govalidator/sponsor/7/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/7/avatar.svg"></a>
  549. <a href="https://opencollective.com/govalidator/sponsor/8/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/8/avatar.svg"></a>
  550. <a href="https://opencollective.com/govalidator/sponsor/9/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/9/avatar.svg"></a>
  551. ## License
  552. [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large)