Introdução
Kotlin é uma linguagem de programação moderna estaticamente tipada que roda na Máquina Virtual Java (JVM) e é totalmente compatível com o ecossistema Java. Graças à sua concisão, segurança e poderosos recursos funcionais, Kotlin se tornou uma das linguagens mais populares para desenvolvimento de aplicações servidoras, especialmente depois que o Google a escolheu como linguagem principal para Android.
Neste artigo, criaremos uma API REST completa em Kotlin, usando o framework leve Ktor e a biblioteca de banco de dados Exposed. Implementaremos um serviço simples para gerenciamento de tarefas (To-Do List) com suporte a todas as operações CRUD (criação, leitura, atualização, exclusão). Todo o processo levará no máximo 30 minutos, se você já tiver instalado o IntelliJ IDEA e o JDK.
1. Configuração do projeto
Para começar, criaremos um novo projeto Kotlin com suporte a Gradle. Abra o IntelliJ IDEA e selecione File → New → Project. No assistente de criação de projeto, escolha Kotlin → JVM.
Passo 1.1: Estrutura do build.gradle.kts
Adicione as seguintes dependências no arquivo build.gradle.kts:
plugins { kotlin("jvm") version "1.9.0" id("io.ktor.plugin") version "2.3.0" kotlin("plugin.serialization") version "1.9.0"}
dependencies { implementation("io.ktor:ktor-server-core:2.3.0") implementation("io.ktor:ktor-server-netty:2.3.0") implementation("io.ktor:ktor-server-content-negotiation:2.3.0") implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.0") implementation("org.jetbrains.exposed:exposed-core:0.41.1") implementation("org.jetbrains.exposed:exposed-dao:0.41.1") implementation("org.jetbrains.exposed:exposed-jdbc:0.41.1") implementation("com.h2database:h2:2.1.214") implementation("ch.qos.logback:logback-classic:1.4.7")}Essas dependências incluem: o próprio framework Ktor, suporte para serialização JSON, a biblioteca Exposed para trabalhar com banco de dados e o banco de dados embutido H2 para testes.
Passo 1.2: Ponto de entrada
Crie o arquivo Application.kt no pacote com.example:
import io.ktor.server.engine.*import io.ktor.server.netty.*import com.example.plugins.*
fun main() { embeddedServer(Netty, port = 8080) { configureSerialization() configureRouting() }.start(wait = true)}2. Configuração de serialização e roteamento
Passo 2.1: Plugins da aplicação
Crie o diretório plugins e o arquivo Serialization.kt:
package com.example.plugins
import io.ktor.serialization.kotlinx.json.*import io.ktor.server.application.*import io.ktor.server.plugins.contentnegotiation.*
fun Application.configureSerialization() { install(ContentNegotiation) { json() }}Passo 2.2: Definição do modelo de dados
Crie o arquivo Models.kt:
package com.example.models
import kotlinx.serialization.Serializable
@Serializabledata class Task( val id: Int = 0, val title: String, val description: String = "", val completed: Boolean = false)3. Trabalhando com o banco de dados
Passo 3.1: Configuração da conexão
Crie o arquivo DatabaseFactory.kt:
package com.example.database
import org.jetbrains.exposed.sql.Databaseimport org.jetbrains.exposed.sql.SchemaUtilsimport org.jetbrains.exposed.sql.transactions.transaction
object DatabaseFactory { fun init() { Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver") transaction { SchemaUtils.create(TasksTable) } }}Passo 3.2: Definição da tabela
No mesmo pacote, crie TasksTable.kt:
package co