Vapor提供了几种不同的方法验证发送到应用的数据。让我们从最常见的方法开始。
Common Usage
默认包含了几种便捷实用的validator
,你可以使用它们来验证发送到应用的数据,也可以将他们组合使用,或者使用自定义的验证方法。
最常见的验证数据的方法:
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()
}
}
这是一个典型的Employee
模型,具有email
和name
属性。 通过将这两个属性声明为Valid<>
类型,来确保这些属性只能包含有效的数据。 Swift类型检查系统将阻止任何未通过验证的数据被存储。
存储的Valid<>
类型的属性,必须调用validated()
方法,这样就可以通过 request.data
返回的数据进行访问了。
Email
是Vapor中包含的validator
,但是Name
不是。我们来看看如何创建validator
:
Valid<OnlyAlphanumeric>
Valid<Email>
Valid<Unique<T>>
Valid<Matches<T>>
Valid<In<T>>
Valid<Contains<T>>
Valid<Count<T>>
Validators vs. ValidationSuites
validators可以有多个配置,例如Count
、Contains
:
let name: Valid<Count<String>> = try "Vapor".validated(by: Count.max(5))
上面是的代码用来验证一个字符串最多不超过5个字符,但是Valid<Count>
只能验证固定数值,并不能准确的告诉我们字符串的具体长度。这个被验证的字符串长度可能小于3,也可能超过100万。
因此,Validator
并不是像程序所希望的那样安全。ValidationSuite
就是用来补充这个缺点的。将多个Validator
或ValidationSuites
组合在一起,来准确的判断什么样的数据需要被验证。
Custom Validator
这是一个创建ValidationSuite
的例子:
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)
}
}
自定义Validator,只需要创建一个方法,使用其他validator或者逻辑来实现自定义验证的逻辑。上面我们创建了一个Name
验证器,只通过由字母和数字组成的字符串,并且字符长度为5~20。
Combining Validator
在上面的Name
验证器中,我们使用&&
连接了validator
,同样的也可以使用||
。(“且”和“或”的逻辑)
也可以使用!
对验证器取反。(“非”的逻辑)
let symbols = input.validated(by: !OnlyAlphanumeric.self)
Testing Validity
validated() throw
是最常用的进行验证的方法,此外还有两个方法:
let passed = input.passes(Count.min(5))
let valid = try input.tested(Count.min(5))
passes()
返回一个Bool类型,表示验证是否通过。tested()
表示是否是否通过验证,如果未通过验证的话则会抛出异常。
与validated()
不同的是,validated()
返回的是Valid<>
类型,而tested()
返回的是被验证数据的原始类型。
Validation Failures
Vapor会在ValidationMiddleware
中自动捕获验证失败的信息。你也可以自己捕获失败信息,或者为特定的验证失败情况自定义response
。
do {
//validation here
} catch let error as ValidationErrorProtocol {
print(error.message)
}
<b>总结:</b>Validate提供了数据验证的方法,我们可以使用ValidationSuite
进行组合已满足我们自定义的需求。
passes()
和tested()
是区别于validated()
的验证方式,返回值不同可以方便我们进行不同的操作。