24-Dec

Kotlin, Web

Introduksjon til Ktor

Denne artikkelen tar deg stegvis gjennom hvordan man kan lage et enkelt API som lar deg hente og poste julehilsner ved hjelp av rammeverket Ktor.

2 min read

·

By Robert Kittilsen

·

December 24, 2023

Lettvinne Julehilsener med Ktor

Velkommen til enda en artikkel på Bekk.christmas! I dag på selveste julaften skal vi utforske Ktor, et moderne og lettvektig Kotlin-rammeverk, og bruke det til å lage et enkelt API for å hente og poste julehilsener i ekte juleånd! So lets go-hohoho!

Trinn 1: Besøk Ktor Start-siden

Gå til start.ktor.io i nettleseren din. Her har du muligheten til å konfigurere ditt Ktor-prosjekt ved å velge de nødvendige avhengighetene.

Trinn 2: Konfigurer prosjektet

Velg et passende navn; f.eks "Ktor-julehilsen" og velg "Gradle" som byggverktøy, trykk "add plugins" og legg til følgende avhengigheter:

  • Routing
  • Status-pages
  • Content-negotiation
  • kotlinx-serialization
  • Jackson
  • Exposed

Du kan også legge til flere avhengigheter etter behov.

Trinn 3: Generer prosjektet

Trykk på "Generate" for å laste ned zip-filen som inneholder prosjektet.

Trinn 4: Åpne prosjektet

Pakk ut zip-filen og åpne prosjektmappen i din foretrukne utviklingside, for eksempel IntelliJ IDEA eller Eclipse.

Trinn 5: Konfigurer database

I prosjektets src mappe vil du finne Applikation.kt. I denne filen ser du et enkelt oppsett som konfigerer serialisering, databases og routes. Naviger inn til configureDatabases()-funksjonen i plugins/Databases.kt og ta en titt. Her har start.ktor.io generert opp eksempel kode for interagering med en User database via en user-service. Det finnes også eksempler på routing som tar i bruk denne user-servicen gjennom CRUD-endepunkter.

Vi skal jo eksponere endepunkter for å sende og hente ut julehilsner så her må gjøre noen endringer.

Start med å lage en ChristmasGreetingService.kt:

package com.example.plugins

import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.Serializable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
import org.jetbrains.exposed.sql.transactions.transaction

@Serializable
data class ExposedGreeting(val message: String)
class ChristmasGreetingService(private val database: Database) {
    object Greetings : Table() {
        val id = integer("id").autoIncrement()
        val message = varchar("message", length = 50)

        override val primaryKey = PrimaryKey(id)
    }

    init {
        transaction(database) {
            SchemaUtils.create(Greetings)
        }
    }

    suspend fun <T> dbQuery(block: suspend () -> T): T =
        newSuspendedTransaction(Dispatchers.IO) { block() }

    suspend fun create(greeting: ExposedGreeting): Int = dbQuery {
        Greetings.insert {
            it[message] = greeting.message
        }[Greetings.id]
    }

    suspend fun read(id: Int): ExposedGreeting? {
        return dbQuery {
            Greetings.select { Greetings.id eq id }
                .map { ExposedGreeting(it[Greetings.message]) }
                .singleOrNull()
        }
    }

    suspend fun readAll(): List<ExposedGreeting> {
        return dbQuery {
            Greetings.selectAll()
                .map { ExposedGreeting(it[Greetings.message]) }
        }
    }
}

Her har jeg brukt eksempelet og modifisert koden til å bruke ExposedGreeting som utgangspunkt for interagering med databasen.

Oppdater så Databases.kt med denne koden:

package com.example.plugins

import io.ktor.server.application.*
import org.jetbrains.exposed.sql.*

fun Application.configureDatabases(): ChristmasGreetingService {
    val database = Database.connect(
        url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1",
        user = "root",
        driver = "org.h2.Driver",
        password = "",
    )
    return ChristmasGreetingService(database)
}

Nå har du en fungerende database og en service for å hente og legge til hilsener.

Trinn 6: Legg opp Routes

Naviger til Routing.kt og modifiser den på følgende måte:

package com.example.plugins

import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.plugins.statuspages.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*

fun Application.configureRouting(greetingService: ChristmasGreetingService) {
    install(StatusPages) {
        exception<Throwable> { call, cause ->
            call.respondText(text = "500: $cause" , status = HttpStatusCode.InternalServerError)
        }
    }
    routing {
        post("/julehilsener") {
            val greeting = call.receive<ExposedGreeting>()
            val id = greetingService.create(greeting)
            call.respond(HttpStatusCode.Created, id)
        }
        get("/julehilsener/{id}") {
            val id = call.parameters["id"]?.toInt() ?: throw IllegalArgumentException("Invalid ID")
            val greeting = greetingService.read(id)
            if (greeting != null) {
                call.respond(HttpStatusCode.OK, greeting)
            } else {
                call.respond(HttpStatusCode.NotFound)
            }
        }
        get("/julehilsener") {
            val greetings = greetingService.readAll()
            call.respond(HttpStatusCode.OK, greetings)
        }
    }
}

Her tar vi bruk julehilsen-servicen og lager endepunkter for å poste og hente en spesifikk julehilsen samt. alle julehilsener.

Trinn 7: Flett alt sammen

Endre Applikation.kt til å se slik ut:

package com.example

import com.example.plugins.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*

fun main() {
    embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module)
        .start(wait = true)
}

fun Application.module() {
    configureSerialization()
    configureRouting(configureDatabases())
}

Og Voilá! Du har et fungerende API for å sende og hente ut julehilsener.

Er'kke verst det?

Oppsummering:

Nå vet du mer om hvordan Ktor fungerer og hvor lett det er å få opp noe som fungerer. Anbefaler å ta en titt på Ktor sin dokumentasjon for videre læring. Dokumentasjonen er, i klassisk JetBrains stil, utrolig sweet å lese og navigere i -> ktor.io

Takk for at du tok turen innom, ha en fortsatt God jul og kotlin-programmering! 🎄🚀

Up next...

Loading…

Loading…