Slide 1

Slide 1 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 Ktorを試してみた 株式会社 虎の穴 山田 公博 1 Copyright © 2019 Toranoana Inc. All Rights Reserved.

Slide 2

Slide 2 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 自己紹介 名前     :山田 公博 担当業務   :ECサイト開発 業務使用の言語:Java 今期アニメ:五等分の花嫁 2 Copyright © 2019 Toranoana Inc. All Rights Reserved.

Slide 3

Slide 3 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 アジェンダ 1. はじめに 2. Ktorについて 3. 事前準備 4. Features 5. 非同期接続について 6. 実践 7. まとめ 3 Copyright © 2019 Toranoana Inc. All Rights Reserved.

Slide 4

Slide 4 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 1.はじめに 4 ● 本日の内容

Slide 5

Slide 5 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 5 Copyright © 2019 Toranoana Inc. All Rights Reserved. ● 「ケイター」と読みます。 ● Kotlinで開発されています。 ● Kotlin同様 JetBrains社により開発されていま す。 ● 単体では非常にシンプルな micro framework です。 2.Ktorについて

Slide 6

Slide 6 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 6 Copyright © 2019 Toranoana Inc. All Rights Reserved. ● Featuresと呼ばれるHTML Template、認証機 能などの各種機能をプラグイン形式で追加が 可能 ● 非同期処理を行うサーバの開発を容易にでき る ● 標準のサーブレットエンジンの他に、Jetty、 Nettyなどのサーブレットエンジンと差し替え可 能 2.Ktorについて

Slide 7

Slide 7 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 7 Copyright © 2019 Toranoana Inc. All Rights Reserved. ● Featuresと呼ばれるHTML Template、認証機 能などの各種機能をプラグイン形式で追加が 可能 ● 非同期処理を行うサーバの開発を容易にでき る ● 標準のサーブレットエンジンの他に、Jetty、 Nettyなどのサーブレットエンジンと差し替え可 能 2.Ktorについて

Slide 8

Slide 8 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 8 Copyright © 2019 Toranoana Inc. All Rights Reserved. 事前準備として、IntelliJ IDEAを使用した Ktorプロジェクトの作成方法を説明します。 3.事前準備

Slide 9

Slide 9 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 9 Copyright © 2019 Toranoana Inc. All Rights Reserved. 1.Ktorプラグインの追加 3.事前準備 IntelliJ IDEA を起動 し、Welcome画面右 下の「Configure」から 「Plugins」を選択して Plugin画面を表示させ ます。 Plugins を選択しま す。

Slide 10

Slide 10 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 10 Copyright © 2019 Toranoana Inc. All Rights Reserved. 1.Ktorプラグインの追加 3.事前準備 Plugin画面で、画面上 部の検索欄に「Ktor」と 入力すると、Ktorプラ グインが表示されるの で、プラグインの 「Install」ボタンをクリッ クします。 1. Ktorと入力 2. Install をクリック

Slide 11

Slide 11 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 11 Copyright © 2019 Toranoana Inc. All Rights Reserved. 1.Ktorプラグインの追加 3.事前準備 プラグインのインストー ル後はIDEの再起動 ボタンが表示されるの で、ボタンをクリックし て再起動を行います。 Restart IDE をクリック

Slide 12

Slide 12 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 12 Copyright © 2019 Toranoana Inc. All Rights Reserved. 2.Ktorプロジェクトの作成手順 3.事前準備 Welcome画面の 「Create New Project」をクリックしま す。

Slide 13

Slide 13 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 13 Copyright © 2019 Toranoana Inc. All Rights Reserved. 2.Ktorプロジェクトの作成手順 3.事前準備 画面左側の「Ktor」を 選択し、利用するプラ グインを選択して 「Next」ボタンをクリッ クします。 1. Ktor を選択 2. 各種プラグイン を選 択 3. Nextボタンをクリック

Slide 14

Slide 14 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 14 Copyright © 2019 Toranoana Inc. All Rights Reserved. 2.Ktorプロジェクトの作成手順 3.事前準備 「GroupId」「ArtifactId」 を適宜入力し、「Next」 ボタンをクリックしま す。 1. GroupId、ArtifactIdを 適宜入力 2. Nextボタンをクリック

Slide 15

Slide 15 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 15 Copyright © 2019 Toranoana Inc. All Rights Reserved. 2.Ktorプロジェクトの作成手順 3.事前準備 「Project name」を入 力すると「Project location」(プロジェクト のディレクトリの作成 場所)が自動的に変更 されます。内容を確認 後、「Finish」ボタンをク リックします。 1. Project name を入力 2. Finishボタンをクリック

Slide 16

Slide 16 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 16 Copyright © 2019 Toranoana Inc. All Rights Reserved. 2.Ktorプロジェクトの作成手順 3.事前準備 Gradleの設定画面が 表示されるので「Use auto-import」をチェッ ク状態に変更後、 「OK」ボタンをクリック します。 1. Use auto-import をチェック 2. OKボタンをクリック

Slide 17

Slide 17 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 17 Copyright © 2019 Toranoana Inc. All Rights Reserved. 2.Ktorプロジェクトの作成手順 3.事前準備 プロジェクト画面が表 示されて完了です。

Slide 18

Slide 18 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 18 Copyright © 2019 Toranoana Inc. All Rights Reserved. Ktorの公式サイトで紹介されている Guides を参考に、Ktorにプラグインとして提供され ているFeatures(機能)を見ていきます。 https://ktor.io/quickstart/guides.html 4. Features

Slide 19

Slide 19 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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 { (中略) } } (以下略)

Slide 20

Slide 20 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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パラメータを扱うこ とも可能です。

Slide 21

Slide 21 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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を 生成できるようになります。

Slide 22

Slide 22 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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を生 成できるようになります。

Slide 23

Slide 23 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 23 Copyright © 2019 Toranoana Inc. All Rights Reserved. StatusPages 4.Features install(StatusPages) { exception { cause -> call.respond(HttpStatusCode.Unauthorized) } exception { cause -> call.respond(HttpStatusCode.Forbidden) } } class AuthenticationException : RuntimeException() class AuthorizationException : RuntimeException() 例外が発生した際のアクションを 定義できるようになります。

Slide 24

Slide 24 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 24 Copyright © 2019 Toranoana Inc. All Rights Reserved. Sessions 4.Features install(Sessions) { cookie("MY_SESSION") { cookie.extensions["SameSite"] = "lax" } } get("/session/increment") { val session = call.sessions.get() ?: 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)

Slide 25

Slide 25 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 25 Copyright © 2019 Toranoana Inc. All Rights Reserved. Sessions 4.Features install(Sessions) { cookie("MY_SESSION") { cookie.extensions["SameSite"] = "lax" } } get("/session/increment") { val session = call.sessions.get() ?: 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) セッションのサポートを追加しま す。

Slide 26

Slide 26 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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 を求めます。

Slide 27

Slide 27 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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 データを渡しています。

Slide 28

Slide 28 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 28 Copyright © 2019 Toranoana Inc. All Rights Reserved. Freemarker 4.Features <#-- @ftlvariable name=“data” type=“com.example.IndexData” -->
    <#list data.items as item>
  • ${item}
  • #list>
(index.fti)

Slide 29

Slide 29 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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メソッドの追加、ヘッダーの 追加等)

Slide 30

Slide 30 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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のシリアル化を処理します。

Slide 31

Slide 31 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 31 Copyright © 2019 Toranoana Inc. All Rights Reserved. 小まとめ ・必要と思われる機能の大半は揃っているように思う。 ・Kotlinベースの為、Javaのライブラリも使用可能。 4.Features

Slide 32

Slide 32 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 32 Copyright © 2019 Toranoana Inc. All Rights Reserved. KtorはKotlinのコルーチンを利用して開発が されています。 そのコルーチンを利用した非同期処理が可 能なつくりとなっています。 5.非同期処理について

Slide 33

Slide 33 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 33 Copyright © 2019 Toranoana Inc. All Rights Reserved. コルーチンとは ざっくり説明をすると、以下のような特性を持ちます。 ・軽量なスレッドのようなもの ・メインスレッドをブロックせずに非同期に動作させることが できる ・軽量な為、大量に作成することができる 5.非同期処理について

Slide 34

Slide 34 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 34 Copyright © 2019 Toranoana Inc. All Rights Reserved. つまり、 大量の同時アクセスに対応できる 5.非同期処理について

Slide 35

Slide 35 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 35 Copyright © 2019 Toranoana Inc. All Rights Reserved. Ktorで作成されたWebアプリに、Kotlinで作 成したクライアントプログラムで大量のアク セスを試みます。 6.実践

Slide 36

Slide 36 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 36 Copyright © 2019 Toranoana Inc. All Rights Reserved. ・サーバーは新規のKtorプロジェクトで、Features にRoutingだけを指定して作成したものを、そのま ま使用します。 7.実践 fun main(args: Array): 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) } } }

Slide 37

Slide 37 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 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/"

Slide 38

Slide 38 text

虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 虎の穴 38 Copyright © 2019 Toranoana Inc. All Rights Reserved. ・現段階でも使用には耐えそう ・Features(機能)はこれからも増えそう? ・GitHubのリリースの頻度を見ると、 まだ鋭意開発中のフレームワークなので、本格的 に使用する場合はリリースノートなどを追う必要が あるかも 7.まとめ