Kotlin mit Ktor

1. Übersicht

Ktor ist ein Framework zum Erstellen von asynchronen Servern und Clients in verbundenen Systemen mithilfe der leistungsstarken Programmiersprache Kotlin. Es erleichtert die Entwicklung einer eigenständigen Anwendung mit eingebetteten Servern.

In diesem Tutorial erfahren Sie, wie Sie mit Ktor eine eigenständige Serveranwendung erstellen.

2. Einrichten einer Ktor-Anwendung

Beginnen wir mit der Einrichtung des Ktor-Projekts. Wir werden Gradle verwenden , den empfohlenen und einfach zu verwendenden Ansatz. Gradle kann installiert werden, indem Sie den Anweisungen auf der Gradle- Website folgen .

Erstellen Sie die Datei 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' }

Wir haben Ktor und das Ktor Netty Server-Paket importiert. Netty ist der eingebettete Server, den wir in diesem Beispiel verwenden.

3. Erstellen des Servers

Wir erstellen unsere Anwendung, indem wir dem Quellordner src / main / kotlin Code hinzufügen .

Hier erstellen wir die Datei APIServer.kt mit der Hauptmethode:

fun main(args: Array) { } 

Als Nächstes erstellen und starten wir den eingebetteten Netty-Server:

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

Der Server wird an Port 8080 erstellt und gestartet . Wir haben wait = true in der start () -Methode gesetzt, um auf Verbindungen zu warten .

4. Erstellen der API

Fügen wir die API hinzu. Zur Bearbeitung von HTTP-Anforderungen bietet Ktor die Routing- Funktion.

Wir aktivieren die Routing-Funktion mit einem Installationsblock , in dem wir Routen für bestimmte Pfade und HTTP-Methoden definieren können:

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)

In diesem Beispiel verarbeitet der Server eine GET- Anforderung für den Pfad / die Aufgabe und antwortet mit einem Aufgaben- JSON-Objekt . Weitere Informationen zum Installieren von Funktionen finden Sie im Abschnitt Installieren von Funktionen.

5. Ausführen des Servers

Um den Server auszuführen, benötigen wir eine Ausführungsaufgabe in Gradle:

task runServer(type: JavaExec) { main = 'APIServer' classpath = sourceSets.main.runtimeClasspath } 

Um den Server zu starten, rufen wir diese Aufgabe auf:

./gradlew runServer 

Auf unsere API kann dann über // localhost: 8080 / todo zugegriffen werden .

6. Funktionen installieren

Eine Ktor-Anwendung besteht normalerweise aus einer Reihe von Funktionen. Wir können uns Features als Funktionen vorstellen, die in die Anforderungs- und Antwortpipeline eingefügt werden.

Mit der DefaultHeaders- Funktion können wir jeder ausgehenden Antwort Header hinzufügen. Routing ist eine weitere Funktion, mit der wir Routen definieren können, um Anforderungen usw. zu bearbeiten.

Wir können auch unsere Funktionen entwickeln und installieren.

Lassen Sie uns einen Blick darauf werfen, indem Sie jeder Anforderung einen benutzerdefinierten Header hinzufügen, indem Sie die DefaultHeaders- Funktion installieren :

install(DefaultHeaders) { header("X-Developer", "Baeldung") }

Ebenso können wir die vom Ktor-Framework selbst festgelegten Standardheader überschreiben:

install(DefaultHeaders) { header(HttpHeaders.Server, "My Server") }

Die Liste der verfügbaren Standardheader finden Sie in der Klasse io.ktor.features.DefaultHeaders.

7. JSON bedienen

Das manuelle Erstellen von JSON mit String ist nicht einfach. Ktor bietet eine Funktion zum Bereitstellen von Datenobjekten als JSON mithilfe von Gson .

Fügen wir die Gson-Abhängigkeit in unser build.gradle ein :

compile "io.ktor:ktor-gson:$ktor_version"

Zum Beispiel verwenden wir ein Datenobjekt mit dem Namen Autor:

data class Author(val name: String, val website: String)

Als nächstes installieren wir die gson- Funktion:

install(ContentNegotiation) { gson { setPrettyPrinting() } }

Zuletzt fügen wir dem Server eine Route hinzu, die ein Autorenobjekt als JSON dient:

get("/author") { val author = Author("baeldung", "baeldung.com") call.respond(author) }

Die Autoren-API dient dem Autorendatenobjekt als JSON .

8. Controller hinzufügen

Um zu verstehen, wie mehrere HTTP-Aktionsanforderungen behandelt werden, erstellen wir eine TODO-Anwendung, mit der der Benutzer TODO-Elemente hinzufügen, löschen, anzeigen und auflisten kann.

Wir beginnen mit dem Hinzufügen einer Todo- Datenklasse:

data class ToDo(var id: Int, val name: String, val description: String, val completed: Boolean) 

Anschließend erstellen wir eine ArrayList für mehrere Todo- Elemente:

val toDoList = ArrayList(); 

Als Nächstes fügen wir die Controller hinzu, um POST-, DELETE- und GET-Anforderungen zu verarbeiten:

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); } } }

Wir haben eine hinzugefügt todo Route und kartiert dann die verschiedenen HTTP - Verben zu diesem Endpunkt anfordern.

9. Fazit

In diesem Artikel haben wir gelernt, wie Sie eine Kotlin-Serveranwendung mit dem Ktor-Framework erstellen.

Wir haben in wenigen Minuten eine kleine Serveranwendung erstellt, ohne Boilerplate-Code zu verwenden.

Wie immer finden Sie die Codebeispiele auf GitHub.