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.

506 lines
20 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.v4
  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"] = CustomTypeValidator(func(i interface{}, o interface{}) bool {
  67. // ...
  68. })
  69. // after
  70. govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(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 InRange(value, left, right float64) bool
  90. func IsASCII(str string) bool
  91. func IsAlpha(str string) bool
  92. func IsAlphanumeric(str string) bool
  93. func IsBase64(str string) bool
  94. func IsByteLength(str string, min, max int) bool
  95. func IsCIDR(str string) bool
  96. func IsCreditCard(str string) bool
  97. func IsDNSName(str string) bool
  98. func IsDataURI(str string) bool
  99. func IsDialString(str string) bool
  100. func IsDivisibleBy(str, num string) bool
  101. func IsEmail(str string) bool
  102. func IsFilePath(str string) (bool, int)
  103. func IsFloat(str string) bool
  104. func IsFullWidth(str string) bool
  105. func IsHalfWidth(str string) bool
  106. func IsHexadecimal(str string) bool
  107. func IsHexcolor(str string) bool
  108. func IsHost(str string) bool
  109. func IsIP(str string) bool
  110. func IsIPv4(str string) bool
  111. func IsIPv6(str string) bool
  112. func IsISBN(str string, version int) bool
  113. func IsISBN10(str string) bool
  114. func IsISBN13(str string) bool
  115. func IsISO3166Alpha2(str string) bool
  116. func IsISO3166Alpha3(str string) bool
  117. func IsISO693Alpha2(str string) bool
  118. func IsISO693Alpha3b(str string) bool
  119. func IsISO4217(str string) bool
  120. func IsIn(str string, params ...string) bool
  121. func IsInt(str string) bool
  122. func IsJSON(str string) bool
  123. func IsLatitude(str string) bool
  124. func IsLongitude(str string) bool
  125. func IsLowerCase(str string) bool
  126. func IsMAC(str string) bool
  127. func IsMongoID(str string) bool
  128. func IsMultibyte(str string) bool
  129. func IsNatural(value float64) bool
  130. func IsNegative(value float64) bool
  131. func IsNonNegative(value float64) bool
  132. func IsNonPositive(value float64) bool
  133. func IsNull(str string) bool
  134. func IsNumeric(str string) bool
  135. func IsPort(str string) bool
  136. func IsPositive(value float64) bool
  137. func IsPrintableASCII(str string) bool
  138. func IsRFC3339(str string) bool
  139. func IsRFC3339WithoutZone(str string) bool
  140. func IsRGBcolor(str string) bool
  141. func IsRequestURI(rawurl string) bool
  142. func IsRequestURL(rawurl string) bool
  143. func IsSSN(str string) bool
  144. func IsSemver(str string) bool
  145. func IsTime(str string, format string) bool
  146. func IsURL(str string) bool
  147. func IsUTFDigit(str string) bool
  148. func IsUTFLetter(str string) bool
  149. func IsUTFLetterNumeric(str string) bool
  150. func IsUTFNumeric(str string) bool
  151. func IsUUID(str string) bool
  152. func IsUUIDv3(str string) bool
  153. func IsUUIDv4(str string) bool
  154. func IsUUIDv5(str string) bool
  155. func IsUpperCase(str string) bool
  156. func IsVariableWidth(str string) bool
  157. func IsWhole(value float64) bool
  158. func LeftTrim(str, chars string) string
  159. func Map(array []interface{}, iterator ResultIterator) []interface{}
  160. func Matches(str, pattern string) bool
  161. func NormalizeEmail(str string) (string, error)
  162. func PadBoth(str string, padStr string, padLen int) string
  163. func PadLeft(str string, padStr string, padLen int) string
  164. func PadRight(str string, padStr string, padLen int) string
  165. func Range(str string, params ...string) bool
  166. func RemoveTags(s string) string
  167. func ReplacePattern(str, pattern, replace string) string
  168. func Reverse(s string) string
  169. func RightTrim(str, chars string) string
  170. func RuneLength(str string, params ...string) bool
  171. func SafeFileName(str string) string
  172. func SetFieldsRequiredByDefault(value bool)
  173. func Sign(value float64) float64
  174. func StringLength(str string, params ...string) bool
  175. func StringMatches(s string, params ...string) bool
  176. func StripLow(str string, keepNewLines bool) string
  177. func ToBoolean(str string) (bool, error)
  178. func ToFloat(str string) (float64, error)
  179. func ToInt(str string) (int64, error)
  180. func ToJSON(obj interface{}) (string, error)
  181. func ToString(obj interface{}) string
  182. func Trim(str, chars string) string
  183. func Truncate(str string, length int, ending string) string
  184. func UnderscoreToCamelCase(s string) string
  185. func ValidateStruct(s interface{}) (bool, error)
  186. func WhiteList(str, chars string) string
  187. type ConditionIterator
  188. type CustomTypeValidator
  189. type Error
  190. func (e Error) Error() string
  191. type Errors
  192. func (es Errors) Error() string
  193. func (es Errors) Errors() []error
  194. type ISO3166Entry
  195. type Iterator
  196. type ParamValidator
  197. type ResultIterator
  198. type UnsupportedTypeError
  199. func (e *UnsupportedTypeError) Error() string
  200. type Validator
  201. ```
  202. #### Examples
  203. ###### IsURL
  204. ```go
  205. println(govalidator.IsURL(`http://user@pass:domain.com/path/page`))
  206. ```
  207. ###### ToString
  208. ```go
  209. type User struct {
  210. FirstName string
  211. LastName string
  212. }
  213. str := govalidator.ToString(&User{"John", "Juan"})
  214. println(str)
  215. ```
  216. ###### Each, Map, Filter, Count for slices
  217. Each iterates over the slice/array and calls Iterator for every item
  218. ```go
  219. data := []interface{}{1, 2, 3, 4, 5}
  220. var fn govalidator.Iterator = func(value interface{}, index int) {
  221. println(value.(int))
  222. }
  223. govalidator.Each(data, fn)
  224. ```
  225. ```go
  226. data := []interface{}{1, 2, 3, 4, 5}
  227. var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} {
  228. return value.(int) * 3
  229. }
  230. _ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15}
  231. ```
  232. ```go
  233. data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  234. var fn govalidator.ConditionIterator = func(value interface{}, index int) bool {
  235. return value.(int)%2 == 0
  236. }
  237. _ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10}
  238. _ = govalidator.Count(data, fn) // result = 5
  239. ```
  240. ###### ValidateStruct [#2](https://github.com/asaskevich/govalidator/pull/2)
  241. 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:
  242. ```go
  243. govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
  244. return str == "duck"
  245. })
  246. ```
  247. For completely custom validators (interface-based), see below.
  248. Here is a list of available validators for struct fields (validator - used function):
  249. ```go
  250. "email": IsEmail,
  251. "url": IsURL,
  252. "dialstring": IsDialString,
  253. "requrl": IsRequestURL,
  254. "requri": IsRequestURI,
  255. "alpha": IsAlpha,
  256. "utfletter": IsUTFLetter,
  257. "alphanum": IsAlphanumeric,
  258. "utfletternum": IsUTFLetterNumeric,
  259. "numeric": IsNumeric,
  260. "utfnumeric": IsUTFNumeric,
  261. "utfdigit": IsUTFDigit,
  262. "hexadecimal": IsHexadecimal,
  263. "hexcolor": IsHexcolor,
  264. "rgbcolor": IsRGBcolor,
  265. "lowercase": IsLowerCase,
  266. "uppercase": IsUpperCase,
  267. "int": IsInt,
  268. "float": IsFloat,
  269. "null": IsNull,
  270. "uuid": IsUUID,
  271. "uuidv3": IsUUIDv3,
  272. "uuidv4": IsUUIDv4,
  273. "uuidv5": IsUUIDv5,
  274. "creditcard": IsCreditCard,
  275. "isbn10": IsISBN10,
  276. "isbn13": IsISBN13,
  277. "json": IsJSON,
  278. "multibyte": IsMultibyte,
  279. "ascii": IsASCII,
  280. "printableascii": IsPrintableASCII,
  281. "fullwidth": IsFullWidth,
  282. "halfwidth": IsHalfWidth,
  283. "variablewidth": IsVariableWidth,
  284. "base64": IsBase64,
  285. "datauri": IsDataURI,
  286. "ip": IsIP,
  287. "port": IsPort,
  288. "ipv4": IsIPv4,
  289. "ipv6": IsIPv6,
  290. "dns": IsDNSName,
  291. "host": IsHost,
  292. "mac": IsMAC,
  293. "latitude": IsLatitude,
  294. "longitude": IsLongitude,
  295. "ssn": IsSSN,
  296. "semver": IsSemver,
  297. "rfc3339": IsRFC3339,
  298. "rfc3339WithoutZone": IsRFC3339WithoutZone,
  299. "ISO3166Alpha2": IsISO3166Alpha2,
  300. "ISO3166Alpha3": IsISO3166Alpha3,
  301. ```
  302. Validators with parameters
  303. ```go
  304. "range(min|max)": Range,
  305. "length(min|max)": ByteLength,
  306. "runelength(min|max)": RuneLength,
  307. "stringlength(min|max)": StringLength,
  308. "matches(pattern)": StringMatches,
  309. "in(string1|string2|...|stringN)": IsIn,
  310. "rsapub(keylength)" : IsRsaPub,
  311. ```
  312. And here is small example of usage:
  313. ```go
  314. type Post struct {
  315. Title string `valid:"alphanum,required"`
  316. Message string `valid:"duck,ascii"`
  317. Message2 string `valid:"animal(dog)"`
  318. AuthorIP string `valid:"ipv4"`
  319. Date string `valid:"-"`
  320. }
  321. post := &Post{
  322. Title: "My Example Post",
  323. Message: "duck",
  324. Message2: "dog",
  325. AuthorIP: "123.234.54.3",
  326. }
  327. // Add your own struct validation tags
  328. govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
  329. return str == "duck"
  330. })
  331. // Add your own struct validation tags with parameter
  332. govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool {
  333. species := params[0]
  334. return str == species
  335. })
  336. govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$")
  337. result, err := govalidator.ValidateStruct(post)
  338. if err != nil {
  339. println("error: " + err.Error())
  340. }
  341. println(result)
  342. ```
  343. ###### WhiteList
  344. ```go
  345. // Remove all characters from string ignoring characters between "a" and "z"
  346. println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa")
  347. ```
  348. ###### Custom validation functions
  349. Custom validation using your own domain specific validators is also available - here's an example of how to use it:
  350. ```go
  351. import "github.com/asaskevich/govalidator"
  352. type CustomByteArray [6]byte // custom types are supported and can be validated
  353. type StructWithCustomByteArray struct {
  354. ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // multiple custom validators are possible as well and will be evaluated in sequence
  355. Email string `valid:"email"`
  356. CustomMinLength int `valid:"-"`
  357. }
  358. govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool {
  359. switch v := context.(type) { // you can type switch on the context interface being validated
  360. case StructWithCustomByteArray:
  361. // you can check and validate against some other field in the context,
  362. // return early or not validate against the context at all – your choice
  363. case SomeOtherType:
  364. // ...
  365. default:
  366. // expecting some other type? Throw/panic here or continue
  367. }
  368. switch v := i.(type) { // type switch on the struct field being validated
  369. case CustomByteArray:
  370. for _, e := range v { // this validator checks that the byte array is not empty, i.e. not all zeroes
  371. if e != 0 {
  372. return true
  373. }
  374. }
  375. }
  376. return false
  377. }))
  378. govalidator.CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool {
  379. switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation
  380. case StructWithCustomByteArray:
  381. return len(v.ID) >= v.CustomMinLength
  382. }
  383. return false
  384. }))
  385. ```
  386. ###### Custom error messages
  387. Custom error messages are supported via annotations by adding the `~` separator - here's an example of how to use it:
  388. ```go
  389. type Ticket struct {
  390. Id int64 `json:"id"`
  391. FirstName string `json:"firstname" valid:"required~First name is blank"`
  392. }
  393. ```
  394. #### Notes
  395. Documentation is available here: [godoc.org](https://godoc.org/github.com/asaskevich/govalidator).
  396. Full information about code coverage is also available here: [govalidator on gocover.io](http://gocover.io/github.com/asaskevich/govalidator).
  397. #### Support
  398. If you do have a contribution to the package, feel free to create a Pull Request or an Issue.
  399. #### What to contribute
  400. If you don't know what to do, there are some features and functions that need to be done
  401. - [ ] Refactor code
  402. - [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check
  403. - [ ] Create actual list of contributors and projects that currently using this package
  404. - [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues)
  405. - [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions)
  406. - [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new
  407. - [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc
  408. - [ ] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
  409. - [ ] Implement fuzzing testing
  410. - [ ] Implement some struct/map/array utilities
  411. - [ ] Implement map/array validation
  412. - [ ] Implement benchmarking
  413. - [ ] Implement batch of examples
  414. - [ ] Look at forks for new features and fixes
  415. #### Advice
  416. Feel free to create what you want, but keep in mind when you implement new features:
  417. - Code must be clear and readable, names of variables/constants clearly describes what they are doing
  418. - Public functions must be documented and described in source file and added to README.md to the list of available functions
  419. - There are must be unit-tests for any new functions and improvements
  420. ## Credits
  421. ### Contributors
  422. This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
  423. #### Special thanks to [contributors](https://github.com/asaskevich/govalidator/graphs/contributors)
  424. * [Daniel Lohse](https://github.com/annismckenzie)
  425. * [Attila Oláh](https://github.com/attilaolah)
  426. * [Daniel Korner](https://github.com/Dadie)
  427. * [Steven Wilkin](https://github.com/stevenwilkin)
  428. * [Deiwin Sarjas](https://github.com/deiwin)
  429. * [Noah Shibley](https://github.com/slugmobile)
  430. * [Nathan Davies](https://github.com/nathj07)
  431. * [Matt Sanford](https://github.com/mzsanford)
  432. * [Simon ccl1115](https://github.com/ccl1115)
  433. <a href="graphs/contributors"><img src="https://opencollective.com/govalidator/contributors.svg?width=890" /></a>
  434. ### Backers
  435. Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/govalidator#backer)]
  436. <a href="https://opencollective.com/govalidator#backers" target="_blank"><img src="https://opencollective.com/govalidator/backers.svg?width=890"></a>
  437. ### Sponsors
  438. 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)]
  439. <a href="https://opencollective.com/govalidator/sponsor/0/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/0/avatar.svg"></a>
  440. <a href="https://opencollective.com/govalidator/sponsor/1/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/1/avatar.svg"></a>
  441. <a href="https://opencollective.com/govalidator/sponsor/2/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/2/avatar.svg"></a>
  442. <a href="https://opencollective.com/govalidator/sponsor/3/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/3/avatar.svg"></a>
  443. <a href="https://opencollective.com/govalidator/sponsor/4/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/4/avatar.svg"></a>
  444. <a href="https://opencollective.com/govalidator/sponsor/5/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/5/avatar.svg"></a>
  445. <a href="https://opencollective.com/govalidator/sponsor/6/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/6/avatar.svg"></a>
  446. <a href="https://opencollective.com/govalidator/sponsor/7/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/7/avatar.svg"></a>
  447. <a href="https://opencollective.com/govalidator/sponsor/8/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/8/avatar.svg"></a>
  448. <a href="https://opencollective.com/govalidator/sponsor/9/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/9/avatar.svg"></a>
  449. ## License
  450. [![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)