Ktor とは
Ktor は、Kotlin の Web アプリケーションフレームワークです。
Kotlin の本山である JetBrains 社により開発が続けられており、2018年末の v1.0 リリースからアップデートが続き、現在は v.1.4.3 がリリースされています。
軽量であり、高い拡張性を持ち、マルチプラットフォームであり、そして Kotlin の coroutines による非同期処理により高いスケーラビリティを発揮します。
ここでは、Ktor による簡単な Web アプリケーションの作成を、何回かに分けて見ていきたいと思います。
プロジェクト作成
Gradle によりプロジェクトを作成します。
gradle init
タスクにてプロジェクトを生成しましょう。
$ mkdir ktor-example $ cd ktor-example $ gradle init
gradle init
タスクでは以下のようにオプション選択しました。
Select type of project to generate: 1: basic 2: application 3: library 4: Gradle plugin Enter selection (default: basic) [1..4] 2 Select implementation language: 1: C++ 2: Groovy 3: Java 4: Kotlin 5: Scala 6: Swift Enter selection (default: Java) [1..6] 4 Split functionality across multiple subprojects?: 1: no - only one application project 2: yes - application and library projects Enter selection (default: no - only one application project) [1..2] 1 Select build script DSL: 1: Groovy 2: Kotlin Enter selection (default: Kotlin) [1..2] 2 Project name (default: ktor-example): Source package (default: ktor.example):
プロジェクトが作成されたら build.gradle.kts
を以下のように変更します。
plugins { id("org.jetbrains.kotlin.jvm") version "1.4.20" application } repositories { jcenter() } dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib") implementation("io.ktor:ktor-server-netty:1.4.3") implementation("ch.qos.logback:logback-classic:1.2.3") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") } application { mainClass.set("ktor.example.AppKt") }
Ktor では、Netty であったり、Jetty や Tomcat などのサーブレットコンテナを使うことができます。
ここでは、Netty を使うため ktor-server-netty
の依存を追加しました。
それ以外は Gradle の Kotlin DSL の標準的な内容です。
Hello World
App.kt
を以下のように編集します。
package ktor.example import io.ktor.application.* import io.ktor.http.* import io.ktor.response.* import io.ktor.routing.* import io.ktor.server.engine.* import io.ktor.server.netty.* fun main(args: Array<String>) { val server = embeddedServer(Netty, port = 8080) { routing { get("/") { call.respondText("Hello World!", ContentType.Text.Plain) } get("/demo") { call.respondText("HELLO WORLD!") } } } server.start(wait = true) }
embeddedServer
として Netty
を選択し、routing
にて2つのパスを登録しています。
respondText()
により固定の文字列をレスポンスするだけの内容です。
実行してみましょう。
$ ./gradlew run
起動したら http://localhost:8080
にアクセスします。
もう一つのパス http://localhost:8080/demo
でアクセスします。
簡単ですね。
Application オブジェクト
先程の例は簡単でしたが、アプリケーションの構成などが増えた場合には、Ktor により提供される Application オブジェクトを利用すると便利です。
Application オブジェクトは、アプリケーションの構成を定義することで、リクエストを処理できるWebアプリケーションとなります。
Application オブジェクトの拡張関数 module()
を以下のように定義します。
fun Application.module() { install(DefaultHeaders) install(CallLogging) install(Routing) { get("/") { call.respondText("Hello World!", ContentType.Text.Html) } get("/demo") { call.respondText("HELLO WORLD!") } } }
install()
により必要な機能を構成します。
Routing
によりリクエストに応じたルーティングを構成します。
main
関数は以下のようになります。
fun main(args: Array<String>) { embeddedServer(Netty, 8080, watchPaths = listOf("AppKt"), module = Application::module) .start() }
watchPaths
には自動リロードの監視対象のパス文字列を指定します。
module
には先程作成した Application オブジェクトの拡張関数 を指定します。
以下のように実行します。
$ ./gradlew run
アプリケーションが起動し、先程と同様の結果が得られます。
なお、Routing
は以下のように外だしして定義することもできます。
fun Application.module() { routing { root() } } fun Routing.root() { get("/") { call.respondText("Hello World!") } }
アプリケーション設定値の抽出
先程の例では、ポート番号といったアプリケーションの設定を、ソースコードに直接記載していました。
これらの設定を外部ファイルに抜き出しましょう。
app/src/main/resources/application.conf
として設定ファイルを新規作成します。
ktor { deployment { port = 8080 port = ${?PORT} } application { modules = [ ktor.example.AppKt.main ] } }
ポート番号と、アプリケーションモジュールを外部ファイルに抜き出しました。
App.kt
を以下のように編集します。
package ktor.example import io.ktor.application.* import io.ktor.http.* import io.ktor.response.* import io.ktor.routing.* import io.ktor.features.* fun Application.main() { install(DefaultHeaders) install(CallLogging) install(Routing) { get("/") { call.respondText("Hello World!", ContentType.Text.Html) } get("/demo") { call.respondText("HELLO WORLD!") } } }
拡張関数は main()
に変更し、もともとあった main()
関数を削除しました。
build.gradle.kts
で アプリケーションプラグインで指定するメインクラスを、Ktor の io.ktor.server.netty.EngineMain
に変更します。
application { mainClass.set("io.ktor.server.netty.EngineMain") }
これにより application.conf
の設定によりアプリケーションが起動します。
その他、以下のエンジンが利用できます。
- io.ktor.server.cio.EngineMain
- io.ktor.server.tomcat.EngineMain
- io.ktor.server.jetty.EngineMain
- io.ktor.server.netty.EngineMain
application.conf
に ktor.deployment.watch
を設定することで、対象パスを監視し、自動リロードが有効になります。
今回の例ではモジュールのパスが app
となるため以下のように設定します。
ktor { deployment { watch = [ app ] } }
intellij idea であれば、ソースを更新後、Build -> Build Projects とすれば更新が反映されます。
次回に続きます。
- 作者:Dmitry Jemerov,Svetlana Isakova
- 発売日: 2017/10/31
- メディア: Kindle版
- 作者:Josh Skeen,David Greenhalgh
- 発売日: 2019/02/14
- メディア: Kindle版