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.
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! 🎄🚀