Server-Side Swift VaporでネストしたContentや配列のValidation方法
Last Updated on 2023年9月23日 by lemonade
概要
公式ドキュメントに以下のようなオブジェクトの配列やネストがあるJSONをvalidateする方法について説明します。
{
username: string.
age: number,
detail: {
blogURL: string
},
favorites: {
genre: String,
name: String
}[]
}
Vaporの公式ドキュメントを探したのですが、この際にdetailやfavoritesを検証する方法が見当たりません。
結論
以下のSwiftのContentに準拠した構造体があるとします。
import Vapor
struct User: Content {
var username: String
var age: Int
var detail: Detail
var favorites: [Favorite]
struct Detail: Content {
var blogURL: String
}
struct Favorite: Content {
var genre: String
var name: String
}
}
その際には、以下のようなValidationを追加してあげればOKです
import Vapor
extension User: Validatable {
static func validations(_ validations: inout Validations) {
validations.add("username", as: String.self, is: .count(0...1_000))
validations.add("age", as: Int.self, is: .range(0...2_00))
validations.add("detail") { detail in
detail.add("blogURL", as: String.self, is: .url)
}
validations.add(each: "favorites") { (i, favorite) in
favorite.add("genre", as: String.self, is: .count(1...1_000)
favorite.add("name", as: String.self, is: .count(1...1_000)
}
}
}
余談
User.Detailのvalidationを複数箇所から使う場合には以下のように共通化も可能です。
import Vapor
extension User.Detail: Validatable {
static func validations(_ validations: inout Validations) {
validations.add("blogURL", as: String.self, is: .url)
}
}
extension Favorite: Validatable {
static func validations(_ validations: inout Validations) {
validations.add("genre", as: String.self, is: .count(1...1_000)
validations.add("name", as: String.self, is: .count(1...1_000)
}
}
extension User: Validatable {
static func validations(_ validations: inout Validations) {
validations.add("username", as: String.self, is: .count(0...1_000))
validations.add("age", as: Int.self, is: .range(0...200))
validations.add("detail", User.Detail.validations)
validations.add(each: "favorites", ({ Favorite.validations(&$1) }))
validations.add("favorites", as: [Favorite.self], is: !.empty)
}
}