Merge branch 'master' of github.com:qutheory/documentation

# Conflicts:
#	couscous.yml
This commit is contained in:
Tanner Nelson 2016-08-02 16:03:58 -04:00
commit dcb360d174
No known key found for this signature in database
GPG Key ID: 9C24375C64856B76
3 changed files with 116 additions and 7 deletions

View File

@ -50,6 +50,9 @@ menu:
guide-views:
text: Views
relativeUrl: guide/views.html
guide-validation:
text: Validation
relativeUrl: guide/validation.html
http:
name: HTTP
items:

View File

@ -27,7 +27,7 @@ And an example of how this might look:
}
```
What that's saying, is that our application should start a single server named 'default' serving port `8080` on host `0.0.0.0`. This represents the following url: `http://localhost:8080`.
What that's saying, is that our application should start a single server named 'http' serving port `8080` on host `0.0.0.0`. This represents the following url: `http://localhost:8080`.
### Custom Keys
@ -45,7 +45,7 @@ Let's add a custom key to the `servers.json` file:
This can be accessed from your application's config using the following.
```Swift
```swift
let customValue = app.config["server", "http", "custom-key"].string
```
@ -70,13 +70,13 @@ You can access your config directory with the following syntax. `app.config[<#fi
We can access this file by making sure the first argument in our subscript is keys. To get the first name in our list:
```Swift
```swift
let name = app.config["keys", "test-names", 0].string
```
Or our mongo url:
```Swift
```swift
let mongoUrl = app.config["keys", "mongo", "url"].string
```
@ -145,7 +145,7 @@ Let's start with the following JSON files.
Please notice that servers.json, and production/servers.json both declare the same keys. host, and port. In our application, we'll call:
```Swift
```swift
// will load 0.0.0.0 or 127.0.0.1 based on above config
let host = app.config["servers", "http", "host"].string
// will load 9000, or environment variable port.
@ -166,7 +166,7 @@ Arguments set through the command line can be accessed through config's cli file
would be accessible within your application by using the following:
```Swift
```swift
let mongoPassword = app.config["cli", "mongo-password"].string
```
@ -180,6 +180,6 @@ If you want command line arguments set to a file besides "cli", you can use this
would be accessible within your application by using the following:
```Swift
```swift
let analyticsKey = app.config["keys", "analytics"].string
```

106
guide/validation.md Normal file
View File

@ -0,0 +1,106 @@
---
currentMenu: guide-validation
---
# Validation
Vapor provides a few different ways to validate data coming into your application. Let's start by looking at the most common.
## Common Usage
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.
```swift
class Employee {
var email: Valid<Email>
var name: Valid<Name>
init(request: Request) throws {
name = try request.data["name"].validated()
email = try request.data["email"].validated()
}
}
```
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.
```swift
Valid<OnlyAlphanumeric>
Valid<Email>
Valid<Unique<T>>
Valid<Matches<T>>
Valid<In<T>>
Valid<Contains<T>>
Valid<Count<T>>
```
## Validators vs. ValidationSuites
Validators, like `Count` or `Contains` can have multiple configurations. For example:
```swift
let name: Valid<Count<String>> = try "Vapor".validated(by: Count.max(5))
```
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, `Validators` themselves are not as type safe as some applications might desire. `ValidationSuites` fix this. They combine multiple `Validators` and/or `ValidationSuites` together to represent exactly what type of data should be considered valid
## Custom Validator
Here is how to create a custom `ValidationSuite`.
```swift
class Name: ValidationSuite {
static func validate(input value: String) throws {
let evaluation = OnlyAlphanumeric.self
&& Count.min(5)
&& Count.max(20)
try evaluation.validate(input: value)
}
}
```
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 Strings that are between 5 and 20 characters.
Now we can be sure that anything of type Valid<Name> follows these rules.
## Combining Validators
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.
```swift
let symbols = input.validated(by: !OnlyAlphanumeric.self)
```
## Testing Validity
While `validated() throw` is the most common method for validating, there are two others.
```swift
let passed = input.passes(Count.min(5))
let valid = try input.tested(Count.min(5))
```
`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.
## Validation Failures
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.
```swift
do {
//validation here
} catch let error as ValidationErrorProtocol {
print(error.message)
}
```