Skip to content

モジュール

Ktorでは、特定のモジュール内に特定のルートセットを定義することで、モジュールを使用してアプリケーションを構成できます。モジュールはApplicationクラスの_拡張関数_です。以下の例では、module1拡張関数は、/module1のURLパスへのGETリクエストを受け入れるモジュールを定義しています。

kotlin
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*

fun Application.module1() {
    routing {
        get("/module1") {
            call.respondText("Hello from 'module1'!")
        }
    }
}

アプリケーションでのモジュールの読み込みは、サーバーの作成方法によって異なります。embeddedServer関数を使ってコードで作成する方法、またはapplication.conf設定ファイルを使用する方法があります。

特定のモジュールにインストールされたプラグインは、他の読み込まれたモジュールにも有効であることに注意してください。

embeddedServer

通常、embeddedServer関数は、ラムダ引数としてモジュールを暗黙的に受け入れます。コードでの設定のセクションで例を見ることができます。 アプリケーションロジックを別のモジュールに抽出し、このモジュールへの参照をmoduleパラメーターとして渡すこともできます。

kotlin
package com.example

import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*

fun main() {
    embeddedServer(Netty, port = 8080, module = Application::module).start(wait = true)
}

fun Application.module() {
    module1()
    module2()
}

fun Application.module1() {
    routing {
        get("/module1") {
            call.respondText("Hello from 'module1'!")
        }
    }
}

fun Application.module2() {
    routing {
        get("/module2") {
            call.respondText("Hello from 'module2'!")
        }
    }
}

完全な例はこちらで見つけることができます: embedded-server-modules

設定ファイル

application.confまたはapplication.yamlファイルを使用してサーバーを設定する場合、ktor.application.modulesプロパティを使用して読み込むモジュールを指定する必要があります。

com.exampleパッケージに2つ、org.sampleパッケージに1つの、合計3つのモジュールが定義されていると仮定します。

kotlin
package com.example

import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

fun Application.module1() {
    routing {
        get("/module1") {
            call.respondText("Hello from 'module1'!")
        }
    }
}

fun Application.module2() {
    routing {
        get("/module2") {
            call.respondText("Hello from 'module2'!")
        }
    }
}
kotlin
package org.sample

import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*

fun Application.module3() {
    routing {
        get("/module3") {
            call.respondText("Hello from 'module3'!")
        }
    }
}

これらのモジュールを設定ファイルで参照するには、その完全修飾名を提供する必要があります。 完全修飾モジュール名には、クラスの完全修飾名と拡張関数名が含まれます。

shell
ktor {
    application {
        modules = [ com.example.ApplicationKt.module1,
                    com.example.ApplicationKt.module2,
                    org.sample.SampleKt.module3 ]
    }
}
yaml
ktor:
    application:
        modules:
            - com.example.ApplicationKt.module1
            - com.example.ApplicationKt.module2
            - org.sample.SampleKt.module3

完全な例はこちらで見つけることができます: engine-main-modules

並行モジュール読み込み

アプリケーションモジュールを作成する際に、中断可能関数(suspend関数)を使用できます。これにより、アプリケーションの起動時にイベントを非同期で実行できます。これを行うには、suspendキーワードを追加します。

kotlin
suspend fun Application.installEvents() {
    val kubernetesConnection = connect(property<KubernetesConfig>("app.events"))
}

また、すべてのアプリケーションモジュールを独立して起動することもできます。これにより、1つが中断されても、他のモジュールがブロックされることはありません。 これにより、依存性注入のための非シーケンシャルな読み込みが可能になり、場合によっては読み込みが高速化されます。

設定オプション

以下のGradle設定プロパティが利用可能です。

プロパティ説明デフォルト
ktor.application.startupsequential / concurrentアプリケーションモジュールの読み込み方法を定義しますsequential
ktor.application.startupTimeoutMillisLongアプリケーションモジュールの読み込みのタイムアウト (ミリ秒単位)100000

並行モジュール読み込みを有効にする

並行モジュール読み込みを有効にするには、gradle.propertiesファイルに以下のプロパティを追加します。

none
ktor.application.startup = concurrent

依存性注入の場合、以下のモジュールを出現順に問題なく読み込むことができます。

kotlin
suspend fun Application.installEvents() {
    // Suspends until provided
    val kubernetesConnection = dependencies.resolve<KubernetesConnection>()
}

suspend fun Application.loadEventsConnection() {
    dependencies.provide<KubernetesConnection> {
        connect(property<KubernetesConfig>("app.events"))
    }
}

並行モジュール読み込みはシングルスレッドプロセスです。これにより、アプリケーションの内部共有状態における安全でないコレクションによるスレッドの問題を回避できます。