Skip to content
Server Plugin

リクエストバリデーション

必要な依存関係: io.ktor:ktor-server-request-validation

コード例: request-validation

Nativeサーバー
Ktor supports Kotlin/Native and allows you to run a server without an additional runtime or virtual machine.
のサポート: ✅

RequestValidationプラグインは、受信リクエストのボディをバリデーション(検証)する機能を提供します。生のリクエストボディや、シリアライザーを備えたContentNegotiationプラグインがインストールされている場合は、特定のリクエストオブジェクトのプロパティをバリデーションできます。リクエストボディのバリデーションに失敗すると、プラグインはRequestValidationExceptionをスローします。これはStatusPagesプラグインを使用して処理できます。

依存関係の追加

RequestValidationを使用するには、ビルドスクリプトにktor-server-request-validationアーティファクトを含める必要があります。

Kotlin
Groovy
XML

RequestValidationのインストール

RequestValidationプラグインをアプリケーションにインストールするには、指定された

モジュール
Modules allow you to structure your application by grouping routes.
内のinstall関数に渡します。 以下のコードスニペットは、RequestValidationをインストールする方法を示しています。

  • ... embeddedServer関数の呼び出し内。
  • ... Applicationクラスの拡張関数である、明示的に定義されたmodule内。
kotlin
kotlin

RequestValidationプラグインは、特定のルートにインストールすることもできます。 これは、アプリケーションの異なるリソースに対して異なるRequestValidation設定が必要な場合に便利です。

RequestValidationの設定

RequestValidationの設定には、主に3つのステップが含まれます。

  1. ボディ・コンテンツの受信
  2. バリデーション関数の設定
  3. バリデーション例外の処理

1. ボディの受信

RequestValidationプラグインは、型パラメータを指定してreceive関数を呼び出した場合に、リクエストのボディをバリデーションします。例えば、以下のコードスニペットはボディをString値として受信する方法を示しています。

kotlin
routing {
    post("/text") {
        val body = call.receive<String>()
        call.respond(body)
    }
}

2. バリデーション関数の設定

リクエストボディをバリデーションするには、validate関数を使用します。 この関数は、バリデーションの成功または失敗を表すValidationResultオブジェクトを返します。 失敗の結果の場合、RequestValidationExceptionがスローされます。

validate関数には2つのオーバーロードがあり、2つの方法でリクエストボディをバリデーションできます。

  • 1つ目のvalidateオーバーロードでは、リクエストボディを指定された型のオブジェクトとしてアクセスできます。 以下の例は、String値を表すリクエストボディをバリデーションする方法を示しています。

    kotlin
    install(RequestValidation) {
        validate<String> { bodyText ->
            if (!bodyText.startsWith("Hello"))
                ValidationResult.Invalid("Body text should start with 'Hello'")
            else ValidationResult.Valid
        }
    }

    特定のシリアライザーで設定されたContentNegotiationプラグインがインストールされている場合は、オブジェクトのプロパティをバリデーションできます。詳細は例:オブジェクトプロパティのバリデーションを参照してください。

  • 2つ目のvalidateオーバーロードはValidatorBuilderを受け取り、カスタムバリデーションルールを提供できます。 詳細は例:バイト配列のバリデーションを参照してください。

3. バリデーション例外の処理

リクエストのバリデーションに失敗すると、RequestValidationRequestValidationExceptionをスローします。 この例外を使用すると、リクエストボディにアクセスし、そのリクエストに対するすべてのバリデーション失敗の理由を取得できます。

RequestValidationExceptionは、次のようにStatusPagesプラグインを使用して処理できます。

kotlin
install(StatusPages) {
    exception<RequestValidationException> { call, cause ->
        call.respond(HttpStatusCode.BadRequest, cause.reasons.joinToString())
    }
}

完全な例はこちらにあります: request-validation

例:オブジェクトプロパティのバリデーション

この例では、RequestValidationプラグインを使用してオブジェクトプロパティをバリデーションする方法を見ていきます。 サーバーが以下のJSONデータを含むPOSTリクエストを受信すると仮定します。

HTTP
POST http://0.0.0.0:8080/json
Content-Type: application/json

{
  "id": -1,
  "firstName": "Jet",
  "lastName": "Brains"
}

idプロパティのバリデーションを追加するには、以下の手順に従います。

  1. 上記のJSONオブジェクトを記述するCustomerデータクラスを作成します。

    kotlin
    @Serializable
    data class Customer(val id: Int, val firstName: String, val lastName: String)
  2. JSONシリアライザーを使用してContentNegotiationプラグインをインストールします。

    kotlin
    install(ContentNegotiation) {
        json()
    }
  3. 次のようにサーバー側でCustomerオブジェクトを受信します。

    kotlin
    post("/json") {
        val customer = call.receive<Customer>()
        call.respond(customer)
    }
  4. RequestValidationプラグインの設定で、idプロパティが指定された範囲に収まることを確認するバリデーションを追加します。

    kotlin
    install(RequestValidation) {
        validate<Customer> { customer ->
            if (customer.id <= 0)
                ValidationResult.Invalid("A customer ID should be greater than 0")
            else ValidationResult.Valid
        }
    }

    この場合、idの値が0以下であれば、RequestValidationRequestValidationExceptionをスローします。

例:バイト配列のバリデーション

この例では、バイト配列として受信したリクエストボディをバリデーションする方法を見ていきます。 サーバーが以下のテキストデータを含むPOSTリクエストを受信すると仮定します。

HTTP
POST http://localhost:8080/array
Content-Type: text/plain

-1

データをバイト配列として受信してバリデーションするには、以下の手順を実行します。

  1. 次のようにサーバー側でデータを受信します。
    kotlin
    post("/array") {
        val body = call.receive<ByteArray>()
        call.respond(String(body))
    }
  2. 受信したデータをバリデーションするために、ValidatorBuilderを受け取りカスタムバリデーションルールを提供できる2つ目のvalidate 関数オーバーロードを使用します。
    kotlin
    install(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
            }
        }
    }