Котлин с Ктор
1. обзор
Ktor - это платформа для построения асинхронных серверов и клиентов в связанных системах с использованием мощного языка программирования Kotlin. Это облегчает разработку отдельного приложения со встроенными серверами.
В этом руководстве мы собираемся изучить, как создать автономное серверное приложение с помощью Ktor.
2. Настройка приложения Ktor
Начнем с настройки проекта Ktor. Мы будем использоватьGradle, это рекомендуемый и простой в использовании подход. Gradle можно установить, следуя инструкциям наGradle site.
Создайте файлbuild.gradle:
group 'com.example.kotlin'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.2.40'
ext.ktor_version = '0.9.2'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'APIServer.kt'
sourceCompatibility = 1.8
compileKotlin { kotlinOptions.jvmTarget = "1.8" }
compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
kotlin { experimental { coroutines "enable" } }
repositories {
mavenCentral()
jcenter()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
dependencies {
compile "io.ktor:ktor-server-netty:$ktor_version"
compile "ch.qos.logback:logback-classic:1.2.1"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
Мы импортировали Ktor и пакет сервера Ktor netty. Netty - это встроенный сервер, который мы будем использовать в этом примере.
3. Сборка сервера
Мы создаем наше приложение, добавляя код в исходную папкуsrc/main/kotlin.
Здесь мы создаем файлAPIServer.kt с помощью основного метода:
fun main(args: Array) {
}
Далее мы создаем и запускаем встроенный сервер Netty:
embeddedServer(Netty, 8080) {
}.start(wait = true)
Он создаст и запустит сервер на порту8080. Мы установилиwait=true в методеstart() для прослушивания соединений.
4. Создание API
Давайте добавим API. Для обработки HTTP-запросов Ktor предоставляет функциюRouting.
Мы активируемRouting feature с помощью блокаinstall, в котором мы можем определять маршруты для определенных путей и методов HTTP:
val jsonResponse = """{
"id": 1,
"task": "Pay waterbill",
"description": "Pay water bill today",
}"""
embeddedServer(Netty, 8080) {
install(Routing) {
get("/todo") {
call.respondText(jsonResponse, ContentType.Application.Json)
}
}
}.start(wait = true)
В этом примере сервер обработает запросGET для пути/todo и ответит объектомtodo JSON. . Подробнее об установке функций мы узнаем в разделеInstalling Features.с
5. Запуск сервера
Чтобы запустить сервер, нам нужна задача запуска в Gradle:
task runServer(type: JavaExec) {
main = 'APIServer'
classpath = sourceSets.main.runtimeClasspath
}
Чтобы запустить сервер, мы называем эту задачу:
./gradlew runServer
Затем доступ к API можно получить черезhttp://localhost:8080/todo.
6. Установка функций
Приложение Ktor обычно состоит из ряда функций. Мы могли бы думать о функциях как о функциональности, которая внедряется в конвейер запросов и ответов.
Используя функциюDefaultHeaders, мы можем добавлять заголовки к каждому исходящему ответу. Routing - еще одна функция, которая позволяет нам определять маршруты для обработки запросов и т. д.
Мы также можем разработать наши функции и установить их.
Давайте посмотрим, добавив настраиваемый заголовок к каждому запросу, установив функциюDefaultHeaders:
install(DefaultHeaders) {
header("X-Developer", "example")
}
Точно так же мы можем переопределить заголовки по умолчанию, установленные самой структурой Ktor:
install(DefaultHeaders) {
header(HttpHeaders.Server, "My Server")
}
Список доступных заголовков по умолчанию можно найти в классеio.ktor.features.DefaultHeaders.
7. Обслуживание JSON
Создать строковый JSON вручную непросто. Ktor предоставляет возможность обслуживать объекты данных как JSON с использованием Gson.
Давайте добавим зависимость Gson в нашbuild.gradle:
compile "io.ktor:ktor-gson:$ktor_version"
Например, мы используем объект данных с именемAuthor:
data class Author(val name: String, val website: String)
Далее мы устанавливаем функциюgson:
install(ContentNegotiation) {
gson {
setPrettyPrinting()
}
}
Наконец, давайте добавим маршрут к серверу, который обслуживает объект-автор как JSON:
get("/author") {
val author = Author("example", "example.com")
call.respond(author)
}
API автора будет обслуживать объект данных автора какJSON.
8. Добавление контроллеров
Чтобы понять, как обрабатывать несколько запросов HTTP-действий, давайте создадим приложение TODO, которое позволяет пользователю добавлять, удалять, просматривать и перечислять элементы TODO.
Начнем с добавления класса данныхTodo:
data class ToDo(var id: Int, val name: String, val description: String, val completed: Boolean)
Затем мы создаемArrayList для хранения нескольких элементовTodo:
val toDoList = ArrayList();
Далее мы добавляем контроллеры для обработки запросов POST, DELETE и GET:
routing() {
route("/todo") {
post {
var toDo = call.receive();
toDo.id = toDoList.size;
toDoList.add(toDo);
call.respond("Added")
}
delete("/{id}") {
call.respond(toDoList.removeAt(call.parameters["id"]!!.toInt()));
}
get("/{id}") {
call.respond(toDoList[call.parameters["id"]!!.toInt()]);
}
get {
call.respond(toDoList);
}
}
}
Мы добавилиtodoroute, а затем сопоставили запрос различных HTTP-глаголов с этой конечной точкой.
9. Заключение
В этой статье мы узнали, как создать серверное приложение Kotlin с фреймворком Ktor.
Мы создали небольшое серверное приложение за несколько минут без использования стандартного кода.
Как всегда, образцы кода можно найтиover on GitHub.