{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","results":{"codes":[]},"settings":"","params":[]},"next":{"description":"","pages":[]},"title":"Validation","type":"basic","slug":"validation","excerpt":"","body":"Vapor provides a few different ways to validate data coming into your application. Let's start by looking at the most common.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Common Usage\"\n}\n[/block]\nSeveral useful convenience validators are included by default. You can use these to validate data coming into your application, or combine them and create your own. \n\nLet's look at the most common way to validate data.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"class Employee {\\n\\t\\tvar email: Valid<Email>\\n    var name: Valid<Name>\\n\\n    init(request: Request) throws {\\n        name = try request.data[\\\"name\\\"].validated()\\n        email = try request.data[\\\"email\\\"].validated()\\n    }\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nHere we have a typical `Employee` model with an `email` and `name` property. By declaring both of these properties as `Valid<>`, you are ensuring that these properties can only ever contain valid data. The Swift type checking system will prevent anything that does not pass validation from being stored. \n\nTo store something in a `Valid<>` property, you must use the `.validated()` method. This is available for any data returned by `request.data`. \n\n`Email` is a real validator included with Vapor, but `Name` is not. Let's take a look at how you can create a Validator. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"Valid<OnlyAlphanumeric>\\nValid<Email>\\nValid<Unique<T>>\\nValid<Matches<T>>\\nValid<In<T>>\\nValid<Contains<T>>\\nValid<Count<T>>\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Validators vs. ValidationSuites\"\n}\n[/block]\nValidators, like `Count` or `Contains` can have multiple configurations. For example:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"let name: Valid<Count<String>> = try \\\"Vapor\\\".validated(by: Count.max(5))\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\nHere we are validating that the `String` is at most 5 characters long. The type of `Valid<Count>` tells us that the string has been validated to be a certain count, but it does not tell us exactly what that count was. The string could have been validated to be less than three characters or more than one million. \n\nBecause of this, `Validator`s themselves are not as type safe as some applications might desire. `ValidationSuite`s fix this. They combine multiple `Validator`s and/or `ValidationSuite`s together to represent exactly what type of data should be considered valid\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Custom Validator\"\n}\n[/block]\nHere is how to create a custom `ValidationSuite`.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"class Name: ValidationSuite {\\n    static func validate(input value: String) throws {\\n        let evaluation = OnlyAlphanumeric.self\\n            && Count.min(5)\\n            && Count.max(20)\\n\\n        try evaluation.validate(input: value)\\n    }\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nYou only have to implement one method. In this method, use any other validators or logic to create your custom validator. Here we are defining a `Name` as only accepting alphanumeric `String`s that are between 5 and 20 characters. \n\nNow we can be sure that anything of type `Valid<Name>` follows these rules. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Combining Validators\"\n}\n[/block]\nIn the `Name` validator, you can see that `&&` is being used to combine validators. You can use `&&` as well as `||` to combine any validator as you would boolean values with an `if` statement.\n\nYou can also use `!` to invert the validator.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"let symbols = input.validated(by: !OnlyAlphanumeric.self)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Testing Validity\"\n}\n[/block]\nWhile `validated() throw` is the most common method for validating, there are two others. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"let passed = input.passes(Count.min(5))\\nlet valid = try input.tested(Count.min(5))\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n`passes()` returns a `boolean` indicating whether or not the test passed.  `tested()` will throw if the validation does not pass. But unlike `validated()` which returns a `Valid<>` type, `tested()` returns the original type of the item it was called on.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Validation Failures\"\n}\n[/block]\nVapor will automatically catch validation failures in the `ValidationMiddleware`. But you can catch them on your own, or customize responses for certain types of failures.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"do {\\n\\t\\t//validation here\\n} catch let error as ValidationErrorProtocol {\\n    print(error.message)\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]","updates":["5737391b64ad2b170045719a"],"order":8,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"5768701b72cd4c0e000fad25","user":"57086f3d447c410e00221bd1","githubsync":"","version":{"version":"0.12","version_clean":"0.12.0","codename":"Client Clyde","is_stable":false,"is_beta":true,"is_hidden":false,"is_deprecated":true,"categories":["5768701b72cd4c0e000fad19","5768701b72cd4c0e000fad1a","5768701b72cd4c0e000fad1b","5768701b72cd4c0e000fad1c"],"_id":"5768701b72cd4c0e000fad18","releaseDate":"2016-06-20T22:37:15.641Z","__v":1,"createdAt":"2016-06-20T22:37:15.641Z","project":"57086fe855a4690e005de407"},"__v":0,"category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"Guide","slug":"getting-started","order":1,"from_sync":false,"reference":false,"_id":"5768701b72cd4c0e000fad1a","createdAt":"2016-04-09T04:31:52.489Z","__v":0,"version":"5768701b72cd4c0e000fad18","project":"57086fe855a4690e005de407"},"createdAt":"2016-05-07T02:30:28.988Z","parentDoc":null,"project":"57086fe855a4690e005de407"}
Vapor provides a few different ways to validate data coming into your application. Let's start by looking at the most common. [block:api-header] { "type": "basic", "title": "Common Usage" } [/block] Several useful convenience validators are included by default. You can use these to validate data coming into your application, or combine them and create your own. Let's look at the most common way to validate data. [block:code] { "codes": [ { "code": "class Employee {\n\t\tvar email: Valid<Email>\n var name: Valid<Name>\n\n init(request: Request) throws {\n name = try request.data[\"name\"].validated()\n email = try request.data[\"email\"].validated()\n }\n}", "language": "swift" } ] } [/block] Here we have a typical `Employee` model with an `email` and `name` property. By declaring both of these properties as `Valid<>`, you are ensuring that these properties can only ever contain valid data. The Swift type checking system will prevent anything that does not pass validation from being stored. To store something in a `Valid<>` property, you must use the `.validated()` method. This is available for any data returned by `request.data`. `Email` is a real validator included with Vapor, but `Name` is not. Let's take a look at how you can create a Validator. [block:code] { "codes": [ { "code": "Valid<OnlyAlphanumeric>\nValid<Email>\nValid<Unique<T>>\nValid<Matches<T>>\nValid<In<T>>\nValid<Contains<T>>\nValid<Count<T>>", "language": "swift" } ] } [/block] [block:api-header] { "type": "basic", "title": "Validators vs. ValidationSuites" } [/block] Validators, like `Count` or `Contains` can have multiple configurations. For example: [block:code] { "codes": [ { "code": "let name: Valid<Count<String>> = try \"Vapor\".validated(by: Count.max(5))", "language": "text" } ] } [/block] Here we are validating that the `String` is at most 5 characters long. The type of `Valid<Count>` tells us that the string has been validated to be a certain count, but it does not tell us exactly what that count was. The string could have been validated to be less than three characters or more than one million. Because of this, `Validator`s themselves are not as type safe as some applications might desire. `ValidationSuite`s fix this. They combine multiple `Validator`s and/or `ValidationSuite`s together to represent exactly what type of data should be considered valid [block:api-header] { "type": "basic", "title": "Custom Validator" } [/block] Here is how to create a custom `ValidationSuite`. [block:code] { "codes": [ { "code": "class Name: ValidationSuite {\n static func validate(input value: String) throws {\n let evaluation = OnlyAlphanumeric.self\n && Count.min(5)\n && Count.max(20)\n\n try evaluation.validate(input: value)\n }\n}", "language": "swift" } ] } [/block] You only have to implement one method. In this method, use any other validators or logic to create your custom validator. Here we are defining a `Name` as only accepting alphanumeric `String`s that are between 5 and 20 characters. Now we can be sure that anything of type `Valid<Name>` follows these rules. [block:api-header] { "type": "basic", "title": "Combining Validators" } [/block] In the `Name` validator, you can see that `&&` is being used to combine validators. You can use `&&` as well as `||` to combine any validator as you would boolean values with an `if` statement. You can also use `!` to invert the validator. [block:code] { "codes": [ { "code": "let symbols = input.validated(by: !OnlyAlphanumeric.self)", "language": "swift" } ] } [/block] [block:api-header] { "type": "basic", "title": "Testing Validity" } [/block] While `validated() throw` is the most common method for validating, there are two others. [block:code] { "codes": [ { "code": "let passed = input.passes(Count.min(5))\nlet valid = try input.tested(Count.min(5))", "language": "swift" } ] } [/block] `passes()` returns a `boolean` indicating whether or not the test passed. `tested()` will throw if the validation does not pass. But unlike `validated()` which returns a `Valid<>` type, `tested()` returns the original type of the item it was called on. [block:api-header] { "type": "basic", "title": "Validation Failures" } [/block] Vapor will automatically catch validation failures in the `ValidationMiddleware`. But you can catch them on your own, or customize responses for certain types of failures. [block:code] { "codes": [ { "code": "do {\n\t\t//validation here\n} catch let error as ValidationErrorProtocol {\n print(error.message)\n}", "language": "swift" } ] } [/block]