リクエストバリデーション
必要な依存関係: io.ktor:ktor-server-request-validation
コード例: request-validation
RequestValidationプラグインは、受信リクエストのボディをバリデーション(検証)する機能を提供します。生のリクエストボディや、シリアライザーを備えたContentNegotiationプラグインがインストールされている場合は、特定のリクエストオブジェクトのプロパティをバリデーションできます。リクエストボディのバリデーションに失敗すると、プラグインはRequestValidationExceptionをスローします。これはStatusPagesプラグインを使用して処理できます。
依存関係の追加
RequestValidationを使用するには、ビルドスクリプトにktor-server-request-validationアーティファクトを含める必要があります。
RequestValidationのインストール
RequestValidationプラグインをアプリケーションにインストールするには、指定された
install関数に渡します。 以下のコードスニペットは、RequestValidationをインストールする方法を示しています。 - ...
embeddedServer関数の呼び出し内。 - ...
Applicationクラスの拡張関数である、明示的に定義されたmodule内。
RequestValidationプラグインは、特定のルートにインストールすることもできます。 これは、アプリケーションの異なるリソースに対して異なるRequestValidation設定が必要な場合に便利です。
RequestValidationの設定
RequestValidationの設定には、主に3つのステップが含まれます。
1. ボディの受信
RequestValidationプラグインは、型パラメータを指定してreceive関数を呼び出した場合に、リクエストのボディをバリデーションします。例えば、以下のコードスニペットはボディをString値として受信する方法を示しています。
routing {
post("/text") {
val body = call.receive<String>()
call.respond(body)
}
}2. バリデーション関数の設定
リクエストボディをバリデーションするには、validate関数を使用します。 この関数は、バリデーションの成功または失敗を表すValidationResultオブジェクトを返します。 失敗の結果の場合、RequestValidationExceptionがスローされます。
validate関数には2つのオーバーロードがあり、2つの方法でリクエストボディをバリデーションできます。
1つ目の
validateオーバーロードでは、リクエストボディを指定された型のオブジェクトとしてアクセスできます。 以下の例は、String値を表すリクエストボディをバリデーションする方法を示しています。kotlininstall(RequestValidation) { validate<String> { bodyText -> if (!bodyText.startsWith("Hello")) ValidationResult.Invalid("Body text should start with 'Hello'") else ValidationResult.Valid } }特定のシリアライザーで設定された
ContentNegotiationプラグインがインストールされている場合は、オブジェクトのプロパティをバリデーションできます。詳細は例:オブジェクトプロパティのバリデーションを参照してください。2つ目の
validateオーバーロードはValidatorBuilderを受け取り、カスタムバリデーションルールを提供できます。 詳細は例:バイト配列のバリデーションを参照してください。
3. バリデーション例外の処理
リクエストのバリデーションに失敗すると、RequestValidationはRequestValidationExceptionをスローします。 この例外を使用すると、リクエストボディにアクセスし、そのリクエストに対するすべてのバリデーション失敗の理由を取得できます。
RequestValidationExceptionは、次のようにStatusPagesプラグインを使用して処理できます。
install(StatusPages) {
exception<RequestValidationException> { call, cause ->
call.respond(HttpStatusCode.BadRequest, cause.reasons.joinToString())
}
}完全な例はこちらにあります: request-validation
例:オブジェクトプロパティのバリデーション
この例では、RequestValidationプラグインを使用してオブジェクトプロパティをバリデーションする方法を見ていきます。 サーバーが以下のJSONデータを含むPOSTリクエストを受信すると仮定します。
POST http://0.0.0.0:8080/json
Content-Type: application/json
{
"id": -1,
"firstName": "Jet",
"lastName": "Brains"
}idプロパティのバリデーションを追加するには、以下の手順に従います。
上記のJSONオブジェクトを記述する
Customerデータクラスを作成します。kotlin@Serializable data class Customer(val id: Int, val firstName: String, val lastName: String)JSONシリアライザーを使用して
ContentNegotiationプラグインをインストールします。kotlininstall(ContentNegotiation) { json() }次のようにサーバー側で
Customerオブジェクトを受信します。kotlinpost("/json") { val customer = call.receive<Customer>() call.respond(customer) }RequestValidationプラグインの設定で、idプロパティが指定された範囲に収まることを確認するバリデーションを追加します。kotlininstall(RequestValidation) { validate<Customer> { customer -> if (customer.id <= 0) ValidationResult.Invalid("A customer ID should be greater than 0") else ValidationResult.Valid } }この場合、
idの値が0以下であれば、RequestValidationはRequestValidationExceptionをスローします。
例:バイト配列のバリデーション
この例では、バイト配列として受信したリクエストボディをバリデーションする方法を見ていきます。 サーバーが以下のテキストデータを含むPOSTリクエストを受信すると仮定します。
POST http://localhost:8080/array
Content-Type: text/plain
-1データをバイト配列として受信してバリデーションするには、以下の手順を実行します。
- 次のようにサーバー側でデータを受信します。kotlin
post("/array") { val body = call.receive<ByteArray>() call.respond(String(body)) } - 受信したデータをバリデーションするために、
ValidatorBuilderを受け取りカスタムバリデーションルールを提供できる2つ目のvalidate関数オーバーロードを使用します。kotlininstall(RequestValidation) { validate { filter { body -> body is ByteArray } validation { body -> check(body is ByteArray) val intValue = String(body).toInt() if (intValue <= 0) ValidationResult.Invalid("A value should be greater than 0") else ValidationResult.Valid } } }
