1. Общ преглед
Ktor е рамка за изграждане на асинхронни сървъри и клиенти в свързани системи, използващи мощния програмен език Kotlin. Той улеснява разработването на самостоятелно приложение с вградени сървъри.
В този урок ще проучим как да създадем самостоятелно сървърно приложение, използвайки Ktor.
2. Създаване на приложение Ktor
Нека започнем с настройването на проекта Ktor. Ще използваме Gradle, който е препоръчителният и лесен за използване подход. Gradle може да бъде инсталиран, като следвате инструкциите, предоставени на сайта Gradle .
Създайте файла build.gradle :
group 'com.baeldung.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 "//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 предоставя функцията за маршрутизация .
Активираме функцията за маршрутизиране с блок за инсталиране, където можем да дефинираме маршрути за конкретни пътища и 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 обект . Ще научим повече за инсталирането на функции в раздела Инсталиране на функции.
5. Стартиране на сървъра
За да стартираме сървъра, имаме нужда от задача за изпълнение в Gradle:
task runServer(type: JavaExec) { main = 'APIServer' classpath = sourceSets.main.runtimeClasspath }
За да стартираме сървъра, извикваме тази задача:
./gradlew runServer
След това API за достъп може да бъде достъпен чрез // localhost: 8080 / todo.
6. Инсталиране на функции
Приложението Ktor обикновено се състои от поредица от функции. Можем да разглеждаме функциите като функционалност, която се инжектира в тръбопровода за заявки и отговори.
Използвайки функцията DefaultHeaders , можем да добавяме заглавия към всеки изходящ отговор. Маршрутизацията е друга функция, която ни позволява да дефинираме маршрути за обработка на заявки и т.н.
Също така можем да разработим нашите функции и да ги инсталираме.
Нека да разгледаме, като добавим персонализиран заглавие към всяка заявка, като инсталираме функцията DefaultHeaders :
install(DefaultHeaders) { header("X-Developer", "Baeldung") }
По същия начин можем да заменим заглавията по подразбиране, зададени от самата рамка на 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"
Например използваме обект на данни с името Автор:
data class Author(val name: String, val website: String)
След това инсталираме функцията gson :
install(ContentNegotiation) { gson { setPrettyPrinting() } }
И накрая, нека добавим маршрут към сървъра, който обслужва обект автор като JSON:
get("/author") { val author = Author("baeldung", "baeldung.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); } } }
Добавихме todo маршрут и след това картографирахме различните заявки за HTTP глаголи към тази крайна точка.
9. Заключение
В тази статия научихме как да създадем сървърно приложение Kotlin с рамката Ktor.
Създадохме малко сървърно приложение за няколко минути, без да използваме какъвто и да е код.
Както винаги, примерните кодове могат да бъдат намерени в GitHub.