github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/docs_src/src/guide/basics/validation.md (about) 1 --- 2 meta: 3 - name: "og:title" 4 content: "Validation - Goyave" 5 - name: "twitter:title" 6 content: "Validation - Goyave" 7 - name: "title" 8 content: "Validation - Goyave" 9 --- 10 11 # Validation 12 13 [[toc]] 14 15 ## Introduction 16 17 Goyave provides a powerful, yet easy way to validate all incoming data, no matter its type or its format, thanks to a large number of validation rules. 18 19 Incoming requests are validated using **rules set**, which associate rules with each expected field in the request. 20 21 Validation rules can **alter the raw data**. That means that when you validate a field to be number, if the validation passes, you are ensured that the data you'll be using in your controller handler is a `float64`. Or if you're validating an IP, you get a `net.IP` object. 22 23 If a request contains a field with a `nil`/`null` value, and that this field doesn't have the `nullable` rule, the field is **removed** entirely from the request. 24 25 Validation is automatic. You just have to define a rules set and assign it to a route. When the validation doesn't pass, the request is stopped and the validation errors messages are sent as a response, using the correct [language](../advanced/localization.html). The HTTP response code of failed validation is **422 "Unprocessable Entity"**, or **400 "Bad Request"** if the body could not be parsed. 26 27 ::: tip 28 You can customize the validation error messages by editing `resources/lang/<language>/rules.json`. Learn more in the [localization](../advanced/localization.html) section. 29 ::: 30 31 The following features require the `validation` package to be imported. 32 33 ``` go 34 import "github.com/System-Glitch/goyave/v2/validation" 35 ``` 36 37 ## Rules sets 38 39 Rule sets are defined in the same package as the controller, typically in a separate file named `request.go`. Rule sets are named after the name of the controller handler they will be used with, and end with `Request`. For example, a rule set for the `Store` handler will be named `StoreRequest`. If a rule set can be used for multiple handlers, consider using a name suited for all of them. The rules for a store operation are often the same for update operations, so instead of duplicating the set, create one unique set called `UpsertRequest`. 40 41 **Example:** (`http/controller/product/request.go`) 42 ``` go 43 var ( 44 StoreRequest validation.RuleSet = validation.RuleSet{ 45 "name": {"required", "string", "between:3,50"}, 46 "price": {"required", "numeric", "min:0.01"}, 47 "image": {"nullable", "file", "image", "max:2048", "count:1"}, 48 } 49 50 // ... 51 ) 52 ``` 53 54 ::: warning 55 **The order in which you assign rules is important**, as rules are executed in this order. The rules checking for the type of the data should **always be first**, or after `required` and `nullable`. 56 57 If a field is not **required** and is missing from the request, **no rules are checked**! 58 ::: 59 60 ::: tip 61 `validation.RuleSet` is an alias for `map[string][]string`. 62 ::: 63 64 --- 65 66 Once your rules sets are defined, you need to assign them to your routes using the `Validate()` method. Learn more about routing in the [dedicated section](./routing.html). 67 68 ``` go 69 router.Post("/product", product.Store).Validate(product.StoreRequest) 70 ``` 71 72 ## Available validation rules 73 74 ::: table 75 [Required](#required) 76 [Nullable](#nullable) 77 [Numeric](#numeric) 78 [Integer](#integer) 79 [Min](#min-value) 80 [Max](#max-value) 81 [Between](#between-min-max) 82 [Greater than](#greater-than-field) 83 [Greater than or equal](#greater-than-equal-field) 84 [Lower than](#lower-than-field) 85 [Lower than or equal](#lower-than-equal-field) 86 [String](#string) 87 [Array](#array-type) 88 [Distinct](#distinct) 89 [Digits](#digits) 90 [Regex](#regex-pattern) 91 [Email](#email) 92 [Size](#size-value) 93 [Alpha](#alpha) 94 [Alpha dash](#alpha-dash) 95 [Alpha numeric](#alpha-num) 96 [Starts with](#starts-with-value1) 97 [Ends with](#ends-with-value1) 98 [In](#in-value1-value2) 99 [Not in](#not-in-value1-value2) 100 [In array](#in-array-field) 101 [Not in array](#not-in-array-field) 102 [Timezone](#timezone) 103 [IP](#ip) 104 [IPv4](#ipv4) 105 [IPv6](#ipv6) 106 [JSON](#json) 107 [URL](#url) 108 [UUID](#uuid-version) 109 [Bool](#bool) 110 [Same](#same-field) 111 [Different](#different-field) 112 [Confirmed](#confirmed) 113 [File](#file) 114 [MIME](#mime-foo) 115 [Image](#image) 116 [Extension](#extension-foo) 117 [Count](#count-value) 118 [Count min](#count-min-value) 119 [Count max](#count-max-value) 120 [Count between](#count-between-min-max) 121 [Date](#date-format) 122 [Before](#before-date) 123 [Before or equal](#before-equal-date) 124 [After](#after-date) 125 [After or equal](#after-equal-date) 126 [Date equals](#date-equals-date) 127 [Date between](#date-between-date1-date2) 128 ::: 129 130 #### required 131 132 The field under validation must be present. 133 134 If the field is a string, the string must not be empty. If a field is `null` and has the `nullable` rule, the `required` rules passes. As non-nullable fields are removed if they have a `null` value, the `required` rule doesn't pass if a field is `null` and doesn't have the `nullable` rule. 135 136 #### nullable 137 138 The field under validation can have a `nil`/`null` value. If this rule is missing from the rules set, the field will be **removed** if it is `null`. This rule is especially useful when working with JSON requests or with primitives that can contain null values. 139 140 Be sure to check if your field is not null before using it in your handlers. 141 ``` go 142 // In this example, field is numeric 143 if val, exists := request.Data["field"]; exists && val != nil { 144 field, _ := request.Data["field"].(float64) 145 } 146 ``` 147 148 #### numeric 149 150 The field under validation must be numeric. Strings that can be converted to numbers are accepted. 151 This rule converts the field to `float64` if it passes. 152 153 #### integer 154 155 The field under validation must be an integer. Strings that can be converted to an integer are accepted. 156 This rule converts the field to `int` if it passes. 157 158 #### min:value 159 160 Depending on its type, the field under validation must be at least `value`. 161 Strings, numerics, array, and files are evaluated using the same method as the [`size`](#size-value) rule. 162 163 #### max:value 164 165 Depending on its type, the field under validation must not be superior to `value`. 166 Strings, numerics, array, and files are evaluated using the same method as the [`size`](#size-value) rule. 167 168 #### between:min,max 169 170 Depending on its type, the field under validation must be between `min` and `max`. 171 Strings, numerics, array, and files are evaluated using the same method as the [`size`](#size-value) rule. 172 173 #### greater_than:field 174 175 The field under validation must be greater than the given `field`. The two fields must have the same type. 176 Strings, numerics, array, and files are evaluated using the same method as the [`size`](#size-value) rule. 177 178 #### greater_than_equal:field 179 180 The field under validation must be greater or equal to the given `field`. The two fields must have the same type. 181 Strings, numerics, array, and files are evaluated using the same method as the [`size`](#size-value) rule. 182 183 #### lower_than:field 184 185 The field under validation must be lower than the given `field`. The two fields must have the same type. 186 Strings, numerics, array, and files are evaluated using the same method as the [`size`](#size-value) rule. 187 188 #### lower_than_equal:field 189 190 The field under validation must be lower or equal to the given `field`. The two fields must have the same type. 191 Strings, numerics, array, and files are evaluated using the same method as the [`size`](#size-value) rule. 192 193 #### string 194 195 The field under validation must be a string. 196 197 #### array:type 198 199 The field under validation must be an array. The `type` parameter is **optional**. 200 201 If no type is provided, the field has the type `[]interface{}` after validation. If a type is provided, the array is converted to a slice of the correct type, and all values in the array are validated in the same way as standard fields. 202 203 For example, with the rule `array:url`, all values must be valid URLs and the field will be converted to `[]*url.URL`. 204 205 **Available types:** 206 - `string` 207 - `numeric` 208 - `integer` 209 - `timezone` 210 - `ip`, `ipv4`, `ipv6` 211 - `url` 212 - `uuid` 213 - `bool` 214 - `date` 215 216 ::: tip 217 For the `uuid` and `date` types, you can pass a second parameter: `array:date,02-01-2006` 218 ::: 219 220 #### distinct 221 222 The field under validation must be an array and have distinct values. 223 224 #### digits 225 226 The field under validation must be a string and contain only digits. 227 228 #### regex:pattern 229 230 The field under validation must be a string and match the given `pattern`. 231 232 #### email 233 234 The field under validation must be a string and be an email address. 235 236 ::: warning 237 This rule is not enough to properly validate email addresses. The only way to ensure an email address is valid is by sending a confirmation email. 238 ::: 239 240 #### size:value 241 242 Depending on its type, the field under validation must: 243 - Strings: have a length of `value` characters. 244 - Numerics: be equal to `value`. 245 - Arrays: exactly have `value` items. 246 - Files: weight exactly `value` KiB. 247 - *Note: for this rule only (not for `min`, `max`, etc), the size of the file under validation is **rounded** to the closest KiB.* 248 - When the field is a multi-files upload, the size of **all files** is checked. 249 250 ::: warning 251 If the value cannot be validated because its type is unsupported, the rule passes. Therefore, you should always validate the type of the field **before** using the `size`, `min`, `lower_than`, ... rules. 252 ::: 253 254 #### alpha 255 256 The field under validation must be a string and be entirely alphabetic characters. 257 258 #### alpha_dash 259 260 The field under validation must be a string and be entirely alphabetic-numeric characters, dashes or underscores. 261 262 #### alpha_num 263 264 The field under validation must be a string and be entirely alphabetic-numeric characters. 265 266 #### starts_with:value1,... 267 268 The field under validation must be a string and start with of the given values. 269 270 #### ends_with:value1,... 271 272 The field under validation must be a string and end with one of the given values. 273 274 #### in:value1,value2,... 275 276 The field under validation must be a one of the given values. Only numerics and strings are checked. 277 278 #### not_in:value1,value2,... 279 280 The field under validation must not be a one of the given values. Only numerics and strings are checked. 281 282 #### in_array:field 283 284 The field under validation must be a one of the values in the given `field`. Only numerics and strings are checked, and the given `field` must be an array. 285 286 #### not_in_array:field 287 288 The field under validation must not be a one of the values in the given `field`. Only numerics and strings are checked, and the given `field` must be an array. 289 290 #### timezone 291 292 The field under validation must be a string and be a valid timezone. This rule converts the field to `*time.Location` if it passes. 293 294 Valid timezones are: 295 - UTC 296 - Timezones from the IANA Time Zone database, such as `America/New_York` 297 298 The time zone database needed by LoadLocation may not be present on all systems, especially non-Unix systems. The rules looks in the directory or uncompressed zip file 299 named by the `ZONEINFO` environment variable, if any, then looks in known installation locations on Unix systems, and finally looks in `$GOROOT/lib/time/zoneinfo.zip`. 300 301 #### ip 302 303 The field under validation must be a string and be either an IPv4 address or an IPv6 address. 304 This rule converts the field to `net.IP` if it passes. 305 306 #### ipv4 307 308 The field under validation must be a string and be an IPv4 address. 309 This rule converts the field to `net.IP` if it passes. 310 311 #### ipv6 312 313 The field under validation must be a string and be an IPv6 address. 314 This rule converts the field to `net.IP` if it passes. 315 316 #### json 317 318 The field under validation must be a valid JSON string. This rule unmarshals the string and sets the field value to the unmarshalled result. 319 320 #### url 321 322 The field under validation must be a valid URL. 323 This rule converts the field to `*url.URL` if it passes. 324 325 #### uuid:version 326 327 The field under validation must be a string and a valid UUID. 328 329 The `version` parameter is **optional**. 330 - If a `version` is given (`uuid:3`,`uuid:4`,`uuid:5`), the rule will pass only if the version of the UUID matches. 331 - If no `version` is given, any UUID version is accepted. 332 333 This rule converts the field to `uuid.UUID` if it passes. 334 335 #### bool 336 337 The field under validation must be a boolean or one of the following values: 338 - `1`/`0` 339 - `"1"`/`"0"` 340 - `"on"`/`"off"` 341 - `"true"`/`"false"` 342 - `"yes"`/`"no"` 343 344 This rule converts the field to `bool` if it passes. 345 346 #### same:field 347 348 The field under validation must have the same value as the given `field`. For arrays, the two fields must have the same values in the same order. 349 350 The two fields must have the same type. Files are not checked. 351 352 #### different:field 353 354 The field under validation must have a different value from the given `field`. For arrays, the two fields must have different values or not be in the same order. 355 356 The two fields must have the same type. Files are not checked. 357 358 #### confirmed 359 360 The field under validation must have a matching `foo_confirmation`. This rule validate equality in the same way as the [`same`](#same-field) rule. 361 362 For example, if the field under validation is `password`, a matching `password_confirmation` field must be present in the input. 363 364 #### file 365 366 The field under validation must be a file. Multi-files are supported. 367 This rule converts the field to `[]filesystem.File` if it passes. 368 369 #### mime:foo,... 370 371 The field under validation must be a file and match one of the given MIME types. If the field is a multi-files, all files must satisfy this rule. 372 373 #### image 374 375 The field under validation must be a file and match one of the following MIME types: 376 - `image/jpeg` 377 - `image/png` 378 - `image/gif` 379 - `image/bmp` 380 - `image/svg+xml` 381 - `image/webp` 382 383 If the field is a multi-files, all files must satisfy this rule. 384 385 #### extension:foo,... 386 387 The field under validation must be a file and match one of the given extensions. If the field is a multi-files, all files must satisfy this rule. 388 389 #### count:value 390 391 The field under validation must be a multi-file and contain `value` files. 392 393 #### count_min:value 394 395 The field under validation must be a multi-file and contain at least `value` files. 396 397 #### count_max:value 398 399 The field under validation must be a multi-file and may not contain more than `value` files. 400 401 #### count_between:min,max 402 403 The field under validation must be a multi-file and contain between `min` and `max` files. 404 405 #### date:format 406 407 The field under validation must be a string representing a date. The `format` is optional. If no format is given, the `2006-01-02` format is used. 408 409 This rule converts the field to `time.Time` if it passes. 410 411 ::: tip 412 See the [Golang datetime format](https://golang.org/src/time/format.go). 413 ::: 414 415 ::: warning 416 When validating dates by comparing them together, the order of the declaration of the fields in the request is important. For example, if you want to validate that an end date is after a start date, the start date should be declared **before** the end date in the rules set. 417 418 If a date has not been validated and converted yet, the date comparison rules will attempt to parse the dates using the following format: `2006-01-02`. 419 ::: 420 421 #### before:date 422 423 The field under validation must be a value preceding the given date. The `date` must be written using following format: `2006-01-02T15:04:05`. 424 425 If the name of another field is given as a `date`, then the two fields must be a date and the field under validation must be preceding the given field. 426 427 #### before_equal:date 428 429 The field under validation must be a value preceding or equal to the given date. The `date` must be written using following format: `2006-01-02T15:04:05`. 430 431 If the name of another field is given as a `date`, then the two fields must be a date and the field under validation must be preceding or equal to given field. 432 433 #### after:date 434 435 The field under validation must be a value after the given date. The `date` must be written using following format: `2006-01-02T15:04:05`. 436 437 If the name of another field is given as a `date`, then the two fields must be a date and the field under validation must be preceding the given field. 438 439 #### after_equal:date 440 441 The field under validation must be a value after or equal to the given date. The `date` must be written using following format: `2006-01-02T15:04:05`. 442 443 If the name of another field is given as a `date`, then the two fields must be a date and the field under validation must be after or equal to given field. 444 445 #### date_equals:date 446 447 The field under validation must be a value equal to the given date. The `date` must be written using following format: `2006-01-02T15:04:05`. 448 449 If the name of another field is given as a `date`, then the two fields must be a date and the field under validation must be equal to given field. 450 451 #### date_between:date1,date2 452 453 The field under validation must be a value between or equal to the given dates. The given dates must be written using following format: `2006-01-02T15:04:05`. 454 455 If the name of another field is given as a date, then all the fields must be a date and the field under validation must be between or equal to given fields. 456 457 ## Custom rules 458 459 If none of the available validation rules satisfy your needs, you can implement custom validation rules. To do so, create a new file `http/validation/validation.go` in which you are going to define your custom rules. 460 461 Rules definition shouldn't be exported, and start with `validate`. A rule returns a `bool`, indicating if the validation passed or not. 462 463 ``` go 464 func validateCustomFormat(field string, value interface{}, parameters []string, form map[string]interface{}) bool { 465 str, ok := value.(string) 466 467 if ok { // The data under validation is a string 468 return regexp.MustCompile(parameters[0]).MatchString(str) 469 } 470 471 return false // Cannot validate this field 472 } 473 ``` 474 ::: tip 475 - `validation.RuleFunc` is an alias for `func(string, interface{}, []string, map[string]interface{}) bool` 476 - The `form` parameter lets you access the whole form data, and modify it if needed. 477 - The custom rule in the example above validates a string using a regex. If you need this kind of validation, prefer the included `regex` validation rule. 478 ::: 479 480 Now that your rule behavior is defined, you need to **register** your rule. Do this in an `init()` function in your `validation.go` file. 481 482 #### validation.AddRule 483 484 Register a validation rule. 485 486 The rule will be usable in request validation by using the given rule name. 487 488 Type-dependent messages let you define a different message for numeric, string, arrays and files. The language entry used will be "validation.rules.rulename.type" 489 490 | Parameters | Return | 491 |-----------------------------------|--------| 492 | `name string` | `void` | 493 | `rule *validation.RuleDefinition` | | 494 495 **Example:** 496 ``` go 497 func init() { 498 validation.AddRule("custom_format", &validation.RuleDefinition{ 499 Function: validateCustomFormat, 500 RequiredParameters: 1, // Ensure the rule has at least one parameter 501 }) 502 } 503 ``` 504 505 The **RuleDefinition** struct is defined as follows: 506 507 ```go 508 type RuleDefinition struct { 509 510 // The Function field is the function that will be executed 511 Function RuleFunc 512 513 // The minimum amount of parameters 514 RequiredParameters int 515 516 // A type rule is a rule that checks if a field has a certain type 517 // and can convert the raw value to a value fitting. For example, the UUID 518 // rule is a type rule because it takes a string as input, checks if it's a 519 // valid UUID and converts it to a "uuid.UUID". 520 IsType bool 521 522 // Type-dependent rules are rules that can be used with different field types 523 // (numeric, string, arrays and files) and have a different validation messages 524 // depending on the type. 525 // The language entry used will be "validation.rules.rulename.type" 526 IsTypeDependent bool 527 } 528 ``` 529 530 ### Adding a message to your rule 531 532 Finally, you may want to add a custom validation message for your rule so the client knows what's wrong with its request. Open `resources/lang/en-US/rules.json` and add an entry with the name of your rule as key: 533 534 ```json 535 { 536 //... 537 "custom_format": "The :field format is invalid.", 538 } 539 ``` 540 541 If you are supporting multiple languages, don't forget to add this to your other `rules.json` files too. 542 543 ::: tip 544 Learn more about validation rules messages in the [Localization documentation](../advanced/localization.html#rules). 545 ::: 546 547 #### validation.GetFieldType 548 549 <p><Badge text="Since v2.0.0"/></p> 550 551 returns the non-technical type of the given `value` interface. 552 This is used by validation rules to know if the input data is a candidate 553 for validation or not and is especially useful for type-dependent rules. 554 - `numeric` if the value is an int, uint or a float 555 - `string` if the value is a string 556 - `array` if the value is a slice 557 - `file` if the value is a slice of `filesystem.File` 558 - `unsupported` otherwise 559 560 | Parameters | Return | 561 |---------------------|----------| 562 | `value interface{}` | `string` | 563 564 **Example:** 565 ``` go 566 validation.GetFieldType("foo") // "string" 567 validation.GetFieldType(2) // "numeric" 568 validation.GetFieldType(2.4) // "numeric" 569 validation.GetFieldType([]int{1,2}) // "array" 570 ``` 571 572 ## Validating arrays 573 574 <p><Badge text="Since v2.1.0"/></p> 575 576 Validating arrays is easy. All the validation rules, **except the file-related rules and the `confirmed` rule**, can be applied to array values using the prefix `>`. When array values are validated, **all of them** must pass the validation. 577 578 **Example:** 579 ``` go 580 var arrayValidation = validation.RuleSet{ 581 "array": {"required", "array:string", "between:1,5", ">email", ">max:128"}, 582 } 583 ``` 584 In this example, we are validating an array of one to five email addresses, which can't be longer than 128 characters. 585 586 ### N-dimensional arrays 587 588 You can validate n-dimensional arrays. 589 590 **Example:** 591 ``` go 592 var arrayValidation = RuleSet{ 593 "array": {"required", "array", ">array", ">>array:numeric", ">max:3", ">>>max:4"}, 594 } 595 ``` 596 In this example, we are validating a three-dimensional array of numeric values. The second dimension must be made of arrays with a size of 3 or less. The third dimension must contain numbers inferior or equal to 4. The following JSON input passes the validation: 597 ```json 598 { 599 "array": [ 600 [[0.5, 1.42], [0.6, 4, 3]], 601 [[0.6, 1.43], [], [2]] 602 ] 603 } 604 ``` 605 606 ## Placeholders 607 608 Validation messages can use placeholders to inject dynamic values in the validation error message. For example, in the `rules.json` language file: 609 610 ```json 611 "between.string": "The :field must be between :min and :max characters." 612 ``` 613 614 Here, the `:field` placeholder will be replaced by the field name, `:min` with the first parameter and `:max` with the second parameter, effectively giving the following result: 615 616 ``` 617 The password must be between 6 and 32 characters. 618 ``` 619 620 Placeholders are **replacer functions**. In fact, `validation.Placeholder` is an alias for `func(string, string, []string, string) string`. These functions should return the value to replace the placeholder with. 621 622 **Example:** 623 ``` go 624 func simpleParameterPlaceholder(field string, rule string, parameters []string, language string) string { 625 return parameters[0] 626 } 627 ``` 628 629 --- 630 631 Placeholders are implemented in the `http/validation/placeholder.go`. To register a custom placeholder, use the `validation.SetPlaceholder()` function, preferably in the `init()` function of your `placeholder.go` file. 632 633 #### validation.SetPlaceholder 634 635 Sets the replacer function for the given placeholder. Don't include the colon prefix in the placeholder name. 636 637 If a placeholder with this name already exists, the latter will be overridden. 638 639 640 | Parameters | Return | 641 |-----------------------------------|--------| 642 | `placeholderName string` | `void` | 643 | `replacer validation.Placeholder` | | 644 645 **Example:** 646 ``` go 647 validation.SetPlaceholder("min", func(field string, rule string, parameters []string, language string) string { 648 return parameters[0] // Replace ":min" by the first parameter in the rule definition 649 }) 650 ``` 651 652 ### Available placeholders 653 654 #### :field 655 656 `:field` is replaced by the name of the field. If it exists, the replacer with favor the language lines in `fields.json`. 657 658 #### :other 659 660 `:other` is replaced by the name of the field given as first parameter in the rule definition. If it exists, the replacer with favor the language lines in `fields.json`. 661 662 For example, the `same:password_confirmation` rule compares two fields together and returns the following message if the validation fails: 663 ``` 664 The :field and the :other must match. 665 666 The password and the password confirmation must match. 667 ``` 668 669 #### :value 670 671 `:value` is replaced by the first parameter of the rule definition. 672 673 #### :values 674 675 `:values` is replaced by a concatenation of all rule parameters, joined by a comma. 676 677 #### :min 678 679 `:min` is replaced by the first parameter of the rule definition. 680 681 #### :max 682 683 `:max` is replaced by the first parameter of the rule definition, or the second if the rule name contains `between`. 684 685 #### :version 686 687 `:version` is replaced by a concatenation of `v` and the first parameter of the rule definition, or by an empty string if the rule doesn't have any parameter. 688 689 For example, for the `UUID:4` rule, the result would be `v4`. 690 691 #### :date 692 693 `:date` is replaced by the first parameter of the rule definition. If the first parameter is a field name, `:date` will be replaced with the name of the field in the same way as the `:other` placeholder. 694 695 #### :max_date 696 697 `:max_date` is replaced by the second parameter of the rule definition. If the second parameter is a field name, `:max_date` will be replaced with the name of the field in the same way as the `:other` placeholder. 698 699 ## Manual validation 700 701 <p><Badge text="Since v2.1.0"/></p> 702 703 You may need to validate some data manually as part of your business logic. You can use the Goyave validator to do so. 704 705 #### validation.Validate 706 707 Validate the given data with the given rule set. If all validation rules pass, returns an empty `validation.Errors`. 708 709 The third parameter (`isJSON`) tells the function if the data comes from a JSON request. This is used to return the correct message if the given data is `nil` and to correctly handle arrays in url-encoded requests. 710 711 The last parameter (`language`) sets the language of the validation error messages. 712 713 | Parameters | Return | 714 |-------------------------------|---------------------| 715 | `data map[string]interface{}` | `validation.Errors` | 716 | `rules validation.Ruler` | | 717 | `isJSON bool` | | 718 | `language string` | | 719 720 ::: tip 721 - `validation.Errors` is an alias for `map[string][]string`. The key represents the field name and the associated slice contains all already translated validation error messages for this field. 722 - `validation.Ruler` is an interface that both `validation.RuleSet` and `validation.Rules` implement. 723 ::: 724 725 **Example:** 726 ``` go 727 func Store(response *goyave.Response, request *goyave.Request) { 728 data := map[string]interface{}{ 729 "string": "hello world", 730 "number": 42, 731 } 732 733 errors := validation.Validate(data, validation.RuleSet{ 734 "string": {"required", "string"}, 735 "number": {"required", "numeric", "min:10"}, 736 }, true, request.Lang) 737 738 if len(errors) > 0 { 739 response.JSON(http.StatusUnprocessableEntity, map[string]validation.Errors{"validationError": errors}) 740 return 741 } 742 743 // data can be safely used from here 744 // ... 745 } 746 ``` 747 748 ## Alternative syntax 749 750 <p><Badge text="Since v3.0.0"/></p> 751 752 Internally, `validation.RuleSet` is parsed and replaced with a more complex structure the first time it is used: `validation.Rules`. This avoids having to parse rules everytime a request is received. Both `validation.RuleSet` and `validation.Rules` can be used when calling `validation.Validate()`, as they both implement the `validation.Ruler` interface. The syntax for `validation.Rules` is significantly more verbose and harder to read, 753 754 Here is an example of rule definition using `validation.Rules` instead of `validation.RuleSet`: 755 756 ```go 757 rules := &validation.Rules{ 758 Fields: validation.FieldMap{ 759 "email": { 760 Rules: []*validation.Rule{ 761 {Name: "required"}, 762 {Name: "string"}, 763 {Name: "between", Params: []string{"3", "125"}}, 764 {Name: "email"}, 765 }, 766 }, 767 "password": { 768 Rules: []*validation.Rule{ 769 {Name: "required"}, 770 {Name: "string"}, 771 {Name: "between", Params: []string{"6", "64"}}, 772 {Name: "confirmed"}, 773 }, 774 }, 775 "info": { 776 Rules: []*validation.Rule{ 777 {Name: "nullable"}, 778 {Name: "array", Params: []string{"string"}}, 779 {Name: "min", Params: []string{"2"}, ArrayDimension: 1}, 780 }, 781 }, 782 }, 783 } 784 785 // Is the same as: 786 set := validation.RuleSet{ 787 "email": {"required", "string", "between:3,125", "email"}, 788 "password": {"required", "string", "between:6,64", "confirmed"}, 789 "info": {"nullable", "array:string", ">min:2"}, 790 } 791 ``` 792 793 ::: tip 794 - `validation.FieldMap` is an alias for `map[string]*validation.Field` 795 - You can use this syntax if you need commas to be part of the values of a rule parameters. 796 :::