Introdução

Neste tutorial, iremos explorar a construção de APIs RESTful utilizando Kotlin em conjunto com o framework Ktor. O Ktor é um framework leve e assíncrono que permite criar aplicações web de maneira rápida e eficiente. Abordaremos as etapas necessárias para contruir uma API escalável, desde a configuração inicial até a implementação de testes automatizados. Além disso, discutiremos as melhores práticas para garantir que seu código seja limpo, manutenível e performático. Este guia é ideal para desenvolvedores que desejam aproveitar ao máximo a linguagem Kotlin e o Ktor em seus projetos de software.

Etapas

  1. Configuração do Ambiente de Desenvolvimento

    Certifique-se de ter o JDK (Java Development Kit) instalado na sua máquina, juntamente com o Kotlin e o Maven. Você pode verificar as versões utilizando os seguintes comandos. Para instalar o Kotlin, siga as instruções em https://kotlinlang.org/docs/command-line.html.

    commands
    # Verificar versões
    java -version
    kotlin -version
    mvn -version

  2. Criação do Projeto Ktor

    Utilize o IntelliJ IDEA ou qualquer outro IDE para criar um novo projeto Kotlin Ktor. Você pode usar a função ‘New Project’ em IntelliJ e selecionar o ‘Ktor’ como o tipo de projeto. Adicione as seguintes dependências em seu arquivo `build.gradle.kts`: `ktor-server-core`, `ktor-server-netty`, `ktor-server-json`, `ktor-serialization`, e `ktor-server-test`. Essas dependências são essenciais para configurar um servidor e tratar JSON.

    build.gradle.kts
    plugins {
        kotlin("jvm") version "1.5.31"
        application
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation("io.ktor:ktor-server-netty:1.6.6")
        implementation("io.ktor:ktor-serialization:1.6.6")
        testImplementation("io.ktor:ktor-server-test-host:1.6.6")
        testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
        testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
    }
    
    application {
        mainClass.set("com.example.ApplicationKt")
    }

  3. Configuração do Ktor

    Crie um arquivo `Application.kt` na pasta `src/main/kotlin/com/example` e configure o servidor Ktor para responder a requisições HTTP. Vamos definir a rota inicial que retornará um simples ‘Hello World’.

    Application.kt
    package com.example
    
    import io.ktor.application.*
    import io.ktor.features.ContentNegotiation
    import io.ktor.json.*
    import io.ktor.routing.*
    import io.ktor.serialization.*
    import io.ktor.server.engine.*
    import io.ktor.server.netty.*
    
    fun main() {
        embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
            install(ContentNegotiation) {
                json()
            }
            routing {
                get("/") {
                    call.respondText("Hello World")
                }
            }
        }.start(wait = true)
    }

  4. Criação de um Endpoint para Produtos

    Adicione uma rota que permita criar e listar produtos. Primeiro, crie uma classe `Produto` que representará os produtos na aplicação.

    Produto.kt
    package com.example
    
    import kotlinx.serialization.Serializable
    
    @Serializable
    data class Produto(val id: Int, val nome: String, val preco: Double)

  5. Persistência em Memória Simples

    Para simular a persistência dos produtos, crie um repositório em memória que gerencia uma lista de produtos. Adicione uma classe `ProdutoRepository` responsável pela lógica de persistência.

    ProdutoRepository.kt
    package com.example
    
    class ProdutoRepository {
        private val produtos = mutableListOf<Produto>()
    
        fun add(produto: Produto) {
            produtos.add(produto)
        }
    
        fun getAll(): List<Produto> = produtos
    }

  6. Implementação de Endpoints RESTful

    Implemente os endpoints para criar e listar os produtos. Atualize `Application.kt` com as rotas adequadas para manipular os produtos.

    Application.kt (atualizado)
    routing {
        val repository = ProdutoRepository()
        get("/produtos") {
            call.respond(repository.getAll())
        }
    
        post("/produtos") {
            val produto = call.receive<Produto>()
            repository.add(produto)
            call.respondText("Produto criado", status = HttpStatusCode.Created)
        }
    }

  7. Testes de Unidade com Ktor

    Crie testes para validar o funcionamento de sua API. Para isso, crie um arquivo `ApplicationTest.kt` em `src/test/kotlin/com/example` e utilize o Ktor para simular as requisições.

    ApplicationTest.kt
    package com.example
    
    import io.ktor.http.*
    import io.ktor.server.testing.*
    import kotlin.test.*
    
    class ApplicationTest {
        @Test
        fun testRoot() {
            withTestApplication({ main() }) {
                handleRequest(HttpMethod.Get, "/").apply {
                    assertEquals(HttpStatusCode.OK, response.status())
                    assertEquals("Hello World", response.content)
                }
            }
        }
    
        @Test
        fun testAddAndGetProduto() {
            withTestApplication({ main() }) {
                handleRequest(HttpMethod.Post, "/produtos") {
                    addHeader("Content-Type", "application/json")
                    setContent("{\"id\": 1, \"nome\": \"Produto Teste\", \"preco\": 50.0}")
                }
                assertEquals(HttpStatusCode.Created, response.status())
                handleRequest(HttpMethod.Get, "/produtos").apply {
                    assertEquals(HttpStatusCode.OK, response.status())
                    assertTrue(response.content!!.contains("Produto Teste"))
                }
            }
        }
    }

  8. Executando a Aplicação e Testes

    Compile e execute a aplicação usando o Gradle. Utilize as ferramentas de teste para garantir que todos os endpoints funcionem como esperado.

    commands
    # Compilar e executar a aplicação
    ./gradlew run
    # Executar testes
    ./gradlew test

Conclusão

Com este tutorial, você aprendeu a criar uma API RESTful utilizando Kotlin e Ktor, abrangendo desde a configuração do ambiente até a implementação de testes automatizados. O Ktor permite uma abordagem leve e assíncrona para construção de aplicações, ideal para sistemas que demandam escalabilidade e performance. Você agora tem as ferramentas necessárias para explorar mais funcionalidades do Ktor e criar APIs robustas para suas aplicações.

Hashtags

#Kotlin #Ktor #APIsRESTful #DesenvolvimentoDeSoftware #TestesUnitários