虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
Ktorを試してみた
株式会社 虎の穴
山田 公博
1
Copyright © 2019 Toranoana Inc. All Rights Reserved.
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
自己紹介
名前     :山田 公博
担当業務   :ECサイト開発
業務使用の言語:Java
今期アニメ:五等分の花嫁
2
Copyright © 2019 Toranoana Inc. All Rights Reserved.
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
アジェンダ
1. はじめに
2. Ktorについて
3. 事前準備
4. Features
5. 非同期接続について
6. 実践
7. まとめ
3
Copyright © 2019 Toranoana Inc. All Rights Reserved.
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
1.はじめに
4
● 本日の内容
IntelliJ IDEAを使用した Ktor のプロジェク
ト作成方法を確認します。
Ktor の公式サイトに書かれている各種サ
ンプルアプリで使用されているKtorの
Features(機能)を見ていきます。
Ktorの接続耐性を試します。
Copyright © 2019 Toranoana Inc. All Rights Reserved.
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
5
Copyright © 2019 Toranoana Inc. All Rights Reserved.
● 「ケイター」と読みます。
● Kotlinで開発されています。
● Kotlin同様 JetBrains社により開発されていま
す。
● 単体では非常にシンプルな micro framework
です。
2.Ktorについて
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
6
Copyright © 2019 Toranoana Inc. All Rights Reserved.
● Featuresと呼ばれるHTML Template、認証機
能などの各種機能をプラグイン形式で追加が
可能
● 非同期処理を行うサーバの開発を容易にでき
る
● 標準のサーブレットエンジンの他に、Jetty、
Nettyなどのサーブレットエンジンと差し替え可
能
2.Ktorについて
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
7
Copyright © 2019 Toranoana Inc. All Rights Reserved.
● Featuresと呼ばれるHTML Template、認証機
能などの各種機能をプラグイン形式で追加が
可能
● 非同期処理を行うサーバの開発を容易にでき
る
● 標準のサーブレットエンジンの他に、Jetty、
Nettyなどのサーブレットエンジンと差し替え可
能
2.Ktorについて
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
8
Copyright © 2019 Toranoana Inc. All Rights Reserved.
事前準備として、IntelliJ IDEAを使用した
Ktorプロジェクトの作成方法を説明します。
3.事前準備
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
9
Copyright © 2019 Toranoana Inc. All Rights Reserved.
1.Ktorプラグインの追加
3.事前準備
IntelliJ IDEA を起動
し、Welcome画面右
下の「Configure」から
「Plugins」を選択して
Plugin画面を表示させ
ます。
Plugins を選択しま
す。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
10
Copyright © 2019 Toranoana Inc. All Rights Reserved.
1.Ktorプラグインの追加
3.事前準備
Plugin画面で、画面上
部の検索欄に「Ktor」と
入力すると、Ktorプラ
グインが表示されるの
で、プラグインの
「Install」ボタンをクリッ
クします。
1. Ktorと入力
2. Install をクリック
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
11
Copyright © 2019 Toranoana Inc. All Rights Reserved.
1.Ktorプラグインの追加
3.事前準備
プラグインのインストー
ル後はIDEの再起動
ボタンが表示されるの
で、ボタンをクリックし
て再起動を行います。
Restart IDE をクリック
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
12
Copyright © 2019 Toranoana Inc. All Rights Reserved.
2.Ktorプロジェクトの作成手順
3.事前準備
Welcome画面の
「Create New
Project」をクリックしま
す。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
13
Copyright © 2019 Toranoana Inc. All Rights Reserved.
2.Ktorプロジェクトの作成手順
3.事前準備
画面左側の「Ktor」を
選択し、利用するプラ
グインを選択して
「Next」ボタンをクリッ
クします。1. Ktor を選択
2. 各種プラグイン を選
択
3. Nextボタンをクリック
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
14
Copyright © 2019 Toranoana Inc. All Rights Reserved.
2.Ktorプロジェクトの作成手順
3.事前準備
「GroupId」「ArtifactId」
を適宜入力し、「Next」
ボタンをクリックしま
す。
1. GroupId、ArtifactIdを
適宜入力
2. Nextボタンをクリック
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
15
Copyright © 2019 Toranoana Inc. All Rights Reserved.
2.Ktorプロジェクトの作成手順
3.事前準備
「Project name」を入
力すると「Project
location」(プロジェクト
のディレクトリの作成
場所)が自動的に変更
されます。内容を確認
後、「Finish」ボタンをク
リックします。
1. Project name を入力
2. Finishボタンをクリック
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
16
Copyright © 2019 Toranoana Inc. All Rights Reserved.
2.Ktorプロジェクトの作成手順
3.事前準備
Gradleの設定画面が
表示されるので「Use
auto-import」をチェッ
ク状態に変更後、
「OK」ボタンをクリック
します。
1. Use auto-import をチェック
2. OKボタンをクリック
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
17
Copyright © 2019 Toranoana Inc. All Rights Reserved.
2.Ktorプロジェクトの作成手順
3.事前準備
プロジェクト画面が表
示されて完了です。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
18
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Ktorの公式サイトで紹介されている Guides
を参考に、Ktorにプラグインとして提供され
ているFeatures(機能)を見ていきます。
https://ktor.io/quickstart/guides.html
4. Features
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
19
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Routing
4.Features
import io.ktor.routing.*
(中略)
routing {
get("/") {
call.respondText("HELLO WORLD!", contentType =
ContentType.Text.Plain)
}
get("/html-dsl") {
call.respondHtml {
(中略)
}
}
(以下略)
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
20
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Routing
4.Features
import io.ktor.routing.*
(中略)
routing {
get("/") {
call.respondText("HELLO WORLD!", contentType =
ContentType.Text.Plain)
}
get("/html-dsl") {
call.respondHtml {
(中略)
}
}
(以下略)
構造化ルートと関連するハンドラを定義す
ることができます。
つまり、リクエストを受け付けるURLと、そ
れに対するアクションを指定できるように
なります。
Locations というFeaturesを利用すること
で、タイプセーフなURLパラメータを扱うこ
とも可能です。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
21
Copyright © 2019 Toranoana Inc. All Rights Reserved.
HTML DSL
4.Features
get("/html-dsl") {
call.respondHtml {
head {
link(rel = "stylesheet", href = "/styles.css", type = "text/css")
}
body {
h1 { +"HTML" }
ul {
for (n in 1..10) {
li { +"$n" }
}
}
p("myclass") {
+"I am using myclass"
}
}
}
}
Kotlinのコードを使用してHTMLを
生成できるようになります。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
22
Copyright © 2019 Toranoana Inc. All Rights Reserved.
CSS DSL
4.Features
get("/styles.css") {
call.respondCss {
body {
backgroundColor = Color.red
}
p {
fontSize = 2.em
}
rule("p.myclass") {
color = Color.blue
}
}
}
Kotlinのコードを使用してCSSを生
成できるようになります。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
23
Copyright © 2019 Toranoana Inc. All Rights Reserved.
StatusPages
4.Features
install(StatusPages) {
exception<AuthenticationException> { cause ->
call.respond(HttpStatusCode.Unauthorized)
}
exception<AuthorizationException> { cause ->
call.respond(HttpStatusCode.Forbidden)
}
}
class AuthenticationException : RuntimeException()
class AuthorizationException : RuntimeException()
例外が発生した際のアクションを
定義できるようになります。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
24
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Sessions
4.Features
install(Sessions) {
cookie<MySession>("MY_SESSION") {
cookie.extensions["SameSite"] = "lax"
}
}
get("/session/increment") {
val session = call.sessions.get<MySession>() ?: MySession()
call.sessions.set(session.copy(count = session.count + 1))
call.respondText("Counter is ${session.count}. Refresh to increment.")
}
data class MySession(val count: Int = 0)
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
25
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Sessions
4.Features
install(Sessions) {
cookie<MySession>("MY_SESSION") {
cookie.extensions["SameSite"] = "lax"
}
}
get("/session/increment") {
val session = call.sessions.get<MySession>() ?: MySession()
call.sessions.set(session.copy(count = session.count + 1))
call.respondText("Counter is ${session.count}. Refresh to increment.")
}
data class MySession(val count: Int = 0)
セッションのサポートを追加しま
す。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
26
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Static Content
4.Features
// Static feature. Try to access `/static/ktor_logo.svg`
static("/static") {
resources("static")
}
定義された場所から静的ファイル
を配信します。
左記のようなコードの場合、
/static/ktor_logo.svg を指定され
ると/resources/static/
ktor_logo.svg を求めます。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
27
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Freemarker
4.Features
install(FreeMarker) {
templateLoader = ClassTemplateLoader(this::class.java.classLoader,
"templates")
}
get("/html-freemarker") {
call.respond(FreeMarkerContent("index.ftl", mapOf("data" to
IndexData(listOf(1, 2, 3))), ""))
} レスポンスとして、
FreeMarkerContent に指定され
たテンプレートindex.ftiと、mapOf
データを渡しています。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
28
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Freemarker
4.Features
<#-- @ftlvariable name=“data” type=“com.example.IndexData” -->
<html>
<body>
<ul>
<#list data.items as item>
<li>${item}</li>
</#list>
</ul>
</body>
</html>
(index.fti)
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
29
Copyright © 2019 Toranoana Inc. All Rights Reserved.
CORS
4.Features
install(CORS) {
method(HttpMethod.Options)
method(HttpMethod.Put)
method(HttpMethod.Delete)
method(HttpMethod.Patch)
header(HttpHeaders.Authorization)
header("MyCustomHeader")
allowCredentials = true
anyHost() // @TODO: Don't do this in production if possible. Try to limit it.
}
オリジン間リソース共有(CORS)
を有効にする為の設定が行えま
す。
(HTTPメソッドの追加、ヘッダーの
追加等)
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
30
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Jackson
4.Features
install(ContentNegotiation) {
jackson {
enable(SerializationFeature.INDENT_OUTPUT)
}
}
get("/json/jackson") {
call.respond(mapOf("hello" to "world"))
}
Jacksonライブラリを使用して
JSONのシリアル化を処理します。
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
31
Copyright © 2019 Toranoana Inc. All Rights Reserved.
小まとめ
・必要と思われる機能の大半は揃っているように思う。
・Kotlinベースの為、Javaのライブラリも使用可能。
4.Features
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
32
Copyright © 2019 Toranoana Inc. All Rights Reserved.
KtorはKotlinのコルーチンを利用して開発が
されています。
そのコルーチンを利用した非同期処理が可
能なつくりとなっています。
5.非同期処理について
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
33
Copyright © 2019 Toranoana Inc. All Rights Reserved.
コルーチンとは
ざっくり説明をすると、以下のような特性を持ちます。
・軽量なスレッドのようなもの
・メインスレッドをブロックせずに非同期に動作させることが
できる
・軽量な為、大量に作成することができる
5.非同期処理について
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
34
Copyright © 2019 Toranoana Inc. All Rights Reserved.
つまり、
大量の同時アクセスに対応できる
5.非同期処理について
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
35
Copyright © 2019 Toranoana Inc. All Rights Reserved.
Ktorで作成されたWebアプリに、Kotlinで作
成したクライアントプログラムで大量のアク
セスを試みます。
6.実践
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
36
Copyright © 2019 Toranoana Inc. All Rights Reserved.
・サーバーは新規のKtorプロジェクトで、Features
にRoutingだけを指定して作成したものを、そのま
ま使用します。
7.実践
fun main(args: Array<String>): Unit =
io.ktor.server.netty.EngineMain.main(args)
@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
routing {
get("/") {
call.respondText("HELLO WORLD!", contentType =
ContentType.Text.Plain)
}
}
}
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
37
Copyright © 2019 Toranoana Inc. All Rights Reserved.
・クライアント側はKotlinのコルーチンを使用して作
成した非常に簡単なものです。
7.実践
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
repeat(100) {
launch {
val result : = clientCall()
println("$result")
}
}
}
fun clientCall(): String {
val requestUrl = "http://127.0.0.1:8080/"
虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴
38
Copyright © 2019 Toranoana Inc. All Rights Reserved.
・現段階でも使用には耐えそう
・Features(機能)はこれからも増えそう?
・GitHubのリリースの頻度を見ると、
まだ鋭意開発中のフレームワークなので、本格的
に使用する場合はリリースノートなどを追う必要が
あるかも
7.まとめ

サーバサイドKotlinへの入門 Ktor編