Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"}...

64
Ktor Ruslan Ibragimov Kotlin Night Kiev

Transcript of Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"}...

Page 1: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

KtorRuslan Ibragimov

Kotlin NightKiev

Page 2: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Ktor

Page 3: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Why yet another server framework

Hello, World!

Architecture

Features

Modularity

Testing

Configuration

Client

Agenda

Page 4: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Why

Usable with KotlinAsyncCoroutines Support

Page 5: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

One more thing...

Page 6: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Multiplatform

Page 7: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Multiplatform

Page 8: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Hello, World!plugins { kotlin("jvm") version "1.3.31"}

repositories { jcenter()}

dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("ch.qos.logback:logback-classic:1.2.1") implementation("io.ktor:ktor-server-netty:1.2.1") testImplementation("io.ktor:ktor-server-tests:1.2.1")}

Page 9: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Hello, World!

fun main() { embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 10: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Hello, World!

fun main() { embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 11: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Hello, World!

fun main() { embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 12: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Hello, World!

fun main() { embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 13: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Hello, World!

fun main() { embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 14: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

start.ktor.io

Page 15: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application::class

fun main() { embeddedServer(Netty, 8080) { this: Application routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 16: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application::class

fun main() { embeddedServer(Netty, 8080) { this: Application this.routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 17: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application::class

Essentially is pipeline

Page 18: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application::class

Page 19: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application::class

Page 20: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Pipeline Phase

Page 21: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Netty

Page 22: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Servlets

Page 23: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Pipelines

ApplicationCallPipelineApplicationReceivePipelineApplicationSendPipeline

Page 24: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Pipelines

ApplicationCallPipelineApplicationReceivePipeline – ApplicationCall

– ApplicationReceiveRequestApplicationSendPipeline– ApplicationCall

– OutgoingContent

Page 25: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptors

fun main() { embeddedServer(Netty, 8080) { this: Application this.routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 26: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application.intercept

embeddedServer(Netty, 8080) { intercept(ApplicationCallPipeline.Monitoring) { // log request headers call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } }}.start(wait = true)

Page 27: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application.intercept

embeddedServer(Netty, 8080) { intercept(ApplicationCallPipeline.Monitoring) { // log request headers call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } }}.start(wait = true)

Page 28: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application.intercept

embeddedServer(Netty, 8080) { intercept(ApplicationCallPipeline.Monitoring) { // log request headers call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } }}.start(wait = true)

Page 29: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application.intercept

embeddedServer(Netty, 8080) { intercept(ApplicationCallPipeline.Monitoring) { // log request headers call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } }}.start(wait = true)

Page 30: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Application Call

ApplicationRequestResponseAttributes

Page 31: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

FeatureRouting

ContentNegotiation

Auth

Call Logging

CORS

Metrics

Compression

etc. see ApplicationFeature

Page 32: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Feature

routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) }}

install(Routing) { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) }}

Page 33: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Feature

embeddedServer(Netty, 8080) { install(DefaultHeaders) install(CallLogging) // //.}.start(wait = true)

Page 34: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→

intercept(ApplicationCallPipeline.Monitoring) { // log request headers call.request.headers .forEach { name, values /> println("$name: ${values.joinToString()}") }}

Page 35: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→typealias Configuration = Unitclass HeaderLoggingFeature { companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, HeaderLoggingFeature> { override val key = AttributeKey<HeaderLoggingFeature>("HeaderLoggingFeature") override fun install( pipeline: ApplicationCallPipeline, configure: Configuration.() /> Unit ): HeaderLoggingFeature { pipeline.intercept(ApplicationCallPipeline.Monitoring) { call.request.headers .forEach { name, values /> println("$name: ${values.joinToString()}") } } return HeaderLoggingFeature() } }}

Page 36: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→typealias Configuration = Unitclass HeaderLoggingFeature { companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, HeaderLoggingFeature> { override val key = AttributeKey<HeaderLoggingFeature>("HeaderLoggingFeature") override fun install( pipeline: ApplicationCallPipeline, configure: Configuration.() /> Unit ): HeaderLoggingFeature { pipeline.intercept(ApplicationCallPipeline.Monitoring) { call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } } return HeaderLoggingFeature() } }}

Page 37: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→typealias Configuration = Unitclass HeaderLoggingFeature { companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, HeaderLoggingFeature> { override val key = AttributeKey<HeaderLoggingFeature>("HeaderLoggingFeature") override fun install( pipeline: ApplicationCallPipeline, configure: Configuration.() /> Unit ): HeaderLoggingFeature { pipeline.intercept(ApplicationCallPipeline.Monitoring) { call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } } return HeaderLoggingFeature() } }}

Page 38: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→typealias Configuration = Unitclass HeaderLoggingFeature { companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, HeaderLoggingFeature> { override val key = AttributeKey<HeaderLoggingFeature>("HeaderLoggingFeature") override fun install( pipeline: ApplicationCallPipeline, configure: Configuration.() /> Unit ): HeaderLoggingFeature { pipeline.intercept(ApplicationCallPipeline.Monitoring) { call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } } return HeaderLoggingFeature() } }}

Page 39: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→typealias Configuration = Unitclass HeaderLoggingFeature { companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, HeaderLoggingFeature> { override val key = AttributeKey<HeaderLoggingFeature>("HeaderLoggingFeature") override fun install( pipeline: ApplicationCallPipeline, configure: Configuration.() /> Unit ): HeaderLoggingFeature { pipeline.intercept(ApplicationCallPipeline.Monitoring) { call.request.headers .forEach { name, values -> println("$name: ${values.joinToString()}") } } return HeaderLoggingFeature() } }}

Page 40: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→typealias Configuration = Unitclass HeaderLoggingFeature { companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, HeaderLoggingFeature> { override val key = AttributeKey<HeaderLoggingFeature>("HeaderLoggingFeature") override fun install( pipeline: ApplicationCallPipeline, configure: Configuration.() /> Unit ): HeaderLoggingFeature { pipeline.intercept(ApplicationCallPipeline.Monitoring) { call.request.headers .forEach { name, values /> println("$name: ${values.joinToString()}") } } return HeaderLoggingFeature() } }}

Page 41: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Interceptor Feature→

install(HeaderLoggingFeature)

intercept(ApplicationCallPipeline.Monitoring) { // log request headers call.request.headers .forEach { name, values /> println("$name: ${values.joinToString()}") }}

install(HeaderLoggingFeature) { exclusions = listOf("User-Agent")}

Page 42: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Content Negotiation Feature

// response{ "hello" : "world"}

install(ContentNegotiation) { jackson { enable(SerializationFeature.INDENT_OUTPUT) }}

routing { get("/resp") { call.respond(mapOf("hello" to "world")) }}

Page 43: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Static Files Serving Feature

static("/static") { resources("static")}

Page 44: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Modularity

fun main() { embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } } }.start(wait = true)}

Page 45: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Modularity

@ContextDslfun Application.helloWorld() { routing { get("/") { call.respondText("I am Groot!", ContentType.Text.Html) } }}

fun main() { embeddedServer(Netty, 8080) { helloWorld() }.start(wait = true)}

Page 46: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Modularity

fun main() { embeddedServer(Netty, 8080) { configuration() users() applications() }.start(wait = true)}

Page 47: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Testing

@Testfun testRoot() { withTestApplication({ configuration() helloWorld() }) { handleRequest(HttpMethod.Get, "/").apply { assertEquals(HttpStatusCode.OK, response.status()) assertEquals("HELLO WORLD!", response.content) } }}

Page 48: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Testing

@Testfun testRoot() { withTestApplication({ configuration() helloWorld() }) { handleRequest(HttpMethod.Get, "/").apply { assertEquals(HttpStatusCode.OK, response.status()) assertEquals("HELLO WORLD!", response.content) } }}

Page 49: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Testing

@Testfun testRoot() { withTestApplication({ configuration() helloWorld() }) { handleRequest(HttpMethod.Get, "/").apply { assertEquals(HttpStatusCode.OK, response.status()) assertEquals("HELLO WORLD!", response.content) } }}

Page 50: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Autoreloading

// application.confktor { deployment { port = 8080 port = ${?PORT} watch = ["ktor-playground"] } application { modules = [ com.knightkyiv.ApplicationKt.module ] }}

Page 51: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Autoreloading

Page 52: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Autoreloading

Works on JDK8!

Page 53: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Ktor Client

val client = HttpClient(Apache)

Page 54: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Ktor Clientfun Application.myApp() { val client = HttpClient(Apache) routing { get("/call") { val text = client.get<String>( host = "localhost", port = 8081, path = "/text" ) call.respondText(text) } }}

Page 55: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Ktor Clientval client = HttpClient(Apache) { install(JsonFeature)}

val user = client.get<User>( host = "localhost", port = 8081, path = "/json")

Page 56: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Configuration

interface ApplicationConfig { fun property(path: String): ApplicationConfigValue fun propertyOrNull(path: String): ApplicationConfigValue? fun config(path: String): ApplicationConfig fun configList(path: String): List<ApplicationConfig>}

Page 57: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Configuration

deploymentConfig.propertyOrNull("shareWorkGroup") /.getString() /.toBoolean() /.let { shareWorkGroup = it }

Page 58: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Configuration// application.confjdbc { user = "tgto" password = "tgto" url = "jdbc:postgresql://tgto_database:5432/tgto" driver = "org.postgresql.Driver"}

data class JdbcConfig( val user: String, val password: String, val url: String, val driver: String)

Page 59: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Configuration// build.gradle.ktsimplementation("io.github.config4k:config4k:0.4.1")

// Application.moduleval jdbcConfig = ConfigFactory.load().extract<JdbcConfig>("jdbc")

Page 60: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Server Engines

NettyJettyTomcattyServletty 3.0+CIOTestEngine

Page 61: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Client EnginesApacheCIOJettyOkHttpAndroidiOSJs (JavaScript)CurlMockEngine

Page 62: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Ktor Adoption

Total – 4400Spring Boot – 1598 Ktor – 1065

Kotlin Census 2018

Page 63: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

Takeaway

Ktor – connected systems, MPP

Application – Pipeline

Pipeline – Interceptors/Features

Modularity

Testability

Page 64: Kotlin Night Kiev - ruslan.ibragimov.by · Hello, World! plugins {kotlin("jvm") version "1.3.31"} repositories {jcenter()} dependencies {implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")