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!
Gå til start.ktor.io i nettleseren din. Her har du muligheten til å konfigurere ditt Ktor-prosjekt ved å velge de nødvendige avhengighetene.
Velg et passende navn; f.eks "Ktor-julehilsen" og velg "Gradle" som byggverktøy, trykk "add plugins" og legg til følgende avhengigheter:
Du kan også legge til flere avhengigheter etter behov.
Trykk på "Generate" for å laste ned zip-filen som inneholder prosjektet.
Pakk ut zip-filen og åpne prosjektmappen i din foretrukne utviklingside, for eksempel IntelliJ IDEA eller Eclipse.
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.
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.
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?
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! 🎄🚀
Loading…
Loading…