---
title: "Ktor 3.4: OpenAPI, Streaming Duplex e Zstd no Kotlin | Kotlin Brasil"
url: "https://kotlin.dev.br/blog/ktor-3-4-novidades-openapi-streaming-2026/"
markdown_url: "https://kotlin.dev.br/blog/ktor-3-4-novidades-openapi-streaming-2026.MD"
description: "Conheça as novidades do Ktor 3.4.0: geração de OpenAPI via código, streaming duplex OkHttp, compressão Zstd e concorrência estruturada. Guia completo."
date: "2026-04-28"
author: "Karina Melo"
---

# Ktor 3.4: OpenAPI, Streaming Duplex e Zstd no Kotlin | Kotlin Brasil

Conheça as novidades do Ktor 3.4.0: geração de OpenAPI via código, streaming duplex OkHttp, compressão Zstd e concorrência estruturada. Guia completo.


O Ktor é o framework HTTP nativo do ecossistema Kotlin, mantido pela JetBrains, e a versão **3.4.0** chegou com melhorias que impactam diretamente quem desenvolve APIs, microsserviços e aplicações em tempo real. Se você já usa [Ktor para criar APIs](/blog/ktor-criando-apis-kotlin/) ou está planejando migrar do Spring Boot, este artigo cobre tudo que mudou e como aproveitar na prática.

Neste guia, vamos explorar as principais novidades: geração de documentação OpenAPI diretamente do código, streaming duplex com OkHttp, compressão Zstd, o novo plugin de ciclo de vida de requisições e várias outras melhorias.

## Geração de OpenAPI direto do código

Uma das features mais pedidas pela comunidade finalmente chegou ao Ktor 3.4: a capacidade de gerar documentação OpenAPI dinamicamente a partir do código de roteamento, sem precisar manter um arquivo YAML ou JSON separado.

A abordagem anterior exigia manter um arquivo `openapi.yaml` sincronizado manualmente com as rotas — um pesadelo de manutenção em projetos grandes. Agora, com o novo compiler plugin, a documentação vive junto do código:

```kotlin
import io.ktor.server.routing.*
import io.ktor.server.response.*
import io.ktor.http.*

fun Route.messageRoutes() {
    get("/messages") {
        val query = call.parameters["search"]?.parseQueryOrNull()
        call.respond(messageTable.listMessages(query))
    }.describe {
        summary = "Lista todas as mensagens"
        description = "Retorna uma lista paginada de mensagens com filtro opcional."
        parameters {
            query("search") {
                description = "Termo de busca para filtrar mensagens"
                required = false
            }
            query("page") {
                description = "Número da página (começando em 0)"
                required = false
            }
        }
        responses {
            HttpStatusCode.OK {
                description = "Lista de mensagens retornada com sucesso"
                schema = jsonSchema<List<Message>>()
            }
            HttpStatusCode.BadRequest {
                description = "Parâmetros de busca inválidos"
            }
        }
    }

    post("/messages") {
        val message = call.receive<CreateMessageRequest>()
        val created = messageTable.create(message)
        call.respond(HttpStatusCode.Created, created)
    }.describe {
        summary = "Cria uma nova mensagem"
        requestBody {
            schema = jsonSchema<CreateMessageRequest>()
        }
        responses {
            HttpStatusCode.Created {
                schema = jsonSchema<Message>()
            }
        }
    }
}
```

A função `describe` é uma extension function que se encaixa naturalmente no DSL de roteamento do Ktor. A documentação OpenAPI é gerada em runtime e pode ser exposta via endpoint dedicado, facilitando integração com Swagger UI ou outros clientes.

Se você vem do [Spring Boot](/blog/kotlin-spring-boot/), essa abordagem é similar ao SpringDoc, mas sem annotations — tudo via DSL Kotlin idiomático. Para uma implementação passo a passo com Swagger UI, YAML de contrato, exemplos de erro e checklist de CI, veja o tutorial prático de [OpenAPI e Swagger no Ktor](/tutoriais/kotlin-ktor-openapi-swagger/).

## Streaming duplex com OkHttp

O Ktor 3.4 trouxe suporte a **streaming duplex** no cliente OkHttp, permitindo enviar dados no corpo da requisição e receber dados da resposta simultaneamente via HTTP/2. Isso é essencial para cenários como:

- Upload de arquivos grandes com feedback de progresso em tempo real
- Comunicação bidirecional sem WebSocket
- Streaming de dados de IA (como respostas de LLMs)

A configuração é simples:

```kotlin
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*

val client = HttpClient(OkHttp) {
    engine {
        duplexStreamingEnabled = true
    }
}
```

Com o duplex habilitado, você pode criar fluxos bidirecionais:

```kotlin
client.preparePost("https://api.exemplo.com/stream") {
    setBody(object : OutgoingContent.WriteChannelContent() {
        override suspend fun writeTo(channel: ByteWriteChannel) {
            // Envia dados progressivamente
            repeat(100) { i ->
                channel.writeStringUtf8("chunk-$i\n")
                delay(100)
            }
        }
    })
}.execute { response ->
    // Recebe dados enquanto ainda está enviando
    val channel = response.bodyAsChannel()
    while (!channel.isClosedForRead) {
        val line = channel.readUTF8Line() ?: break
        println("Recebido: $line")
    }
}
```

Essa feature é especialmente útil se você trabalha com [gRPC e Kotlin](/blog/grpc-kotlin-coroutines-tutorial-2026/), já que o streaming bidirecional é um padrão comum em comunicação entre microsserviços.

## Compressão Zstd

O Ktor 3.4 adicionou suporte nativo ao **Zstd** (Zstandard), o algoritmo de compressão desenvolvido pelo Facebook que oferece taxas de compressão superiores ao gzip com velocidade de descompressão significativamente maior.

Para habilitar no servidor, basta instalar o módulo dedicado:

```kotlin
import io.ktor.server.plugins.compression.*

fun Application.configureCompression() {
    install(Compression) {
        zstd {
            compressionLevel = 3 // Padrão: bom equilíbrio velocidade/compressão
        }
        gzip {
            priority = 0.9
        }
        deflate {
            priority = 0.5
        }
    }
}
```

O Zstd brilha em cenários onde você transmite payloads JSON grandes — como listas de produtos, logs ou dados analíticos. Em benchmarks internos da JetBrains, o Zstd com nível 3 comprime 20-30% melhor que gzip com velocidade de descompressão até 5x superior.

A dependência é separada para não inflar projetos que não precisam:

```kotlin
// build.gradle.kts
dependencies {
    implementation("io.ktor:ktor-server-compression-zstd:3.4.0")
}
```

## Plugin HttpRequestLifecycle

O novo plugin `HttpRequestLifecycle` resolve um problema antigo: o que acontece com requisições em processamento quando o cliente desconecta? Antes do Ktor 3.4, a coroutine continuava executando até o final, desperdiçando recursos.

Agora, com concorrência estruturada integrada ao ciclo de vida da requisição, operações em andamento são canceladas automaticamente:

```kotlin
import io.ktor.server.plugins.httprequestlifecycle.*

fun Application.configureLifecycle() {
    install(HttpRequestLifecycle)

    routing {
        get("/relatorio-pesado") {
            // Se o cliente desconectar, esta coroutine é cancelada
            val dados = withContext(Dispatchers.IO) {
                // Consulta demorada ao banco de dados
                repository.gerarRelatorioCompleto()
            }
            call.respond(dados)
        }
    }
}
```

Essa feature é particularmente importante para operações que consomem muitos recursos, como geração de relatórios, processamento de imagens ou consultas complexas ao banco. Se você trabalha com [observabilidade em Kotlin](/blog/kotlin-observabilidade/), o cancelamento adequado também gera métricas mais precisas sobre latência real.

## Melhorias em Server-Sent Events

O suporte a SSE (Server-Sent Events) que foi introduzido no Ktor 3.0 recebeu melhorias de estabilidade e desempenho no 3.4. O SSE é ideal para cenários onde o servidor precisa enviar atualizações unidirecionais ao cliente — como notificações, feeds de dados ao vivo e dashboards:

```kotlin
import io.ktor.server.sse.*
import io.ktor.sse.*

fun Application.configureSSE() {
    install(SSE)

    routing {
        sse("/eventos") {
            // Envia eventos a cada segundo
            var contador = 0
            while (true) {
                send(ServerSentEvent(
                    data = """{"tipo": "atualizacao", "valor": ${contador++}}""",
                    event = "dados",
                    id = contador.toString()
                ))
                delay(1000)
            }
        }
    }
}
```

No lado do cliente, o Ktor também oferece suporte nativo:

```kotlin
val client = HttpClient(CIO)

client.sse("https://api.exemplo.com/eventos") {
    incoming.collect { evento ->
        println("Evento recebido: ${evento.data}")
    }
}
```

Se você está considerando entre SSE e WebSocket, o SSE é mais simples quando a comunicação é unidirecional (servidor para cliente) e funciona melhor com proxies e load balancers tradicionais.

## Migração e compatibilidade

O Ktor 3.4 é totalmente compatível com o [Kotlin 2.3.20](/blog/kotlin-2-3-20-novidades/) e funciona com o [Kotlin 2.4.0 Beta](/blog/kotlin-2-4-0-beta-novidades-2026/) sem problemas. A migração a partir do Ktor 3.x anterior é direta — basta atualizar a versão no Gradle:

```kotlin
// build.gradle.kts
val ktor_version = "3.4.0"

dependencies {
    implementation("io.ktor:ktor-server-core:$ktor_version")
    implementation("io.ktor:ktor-server-netty:$ktor_version")
    implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
    implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
}
```

Se você vem do Ktor 2.x, a migração é mais significativa devido à troca do `kotlinx-io`. Consulte o [guia de backend com Ktor](/guias/guia-kotlin-backend-ktor/) para mais detalhes sobre a arquitetura recomendada.

## Conclusão

O Ktor 3.4 consolida o framework como uma opção séria para backend em Kotlin, especialmente para equipes que valorizam a abordagem idiomática do Kotlin com [coroutines](/blog/coroutines-kotlin/) e DSLs. A geração de OpenAPI via código elimina uma dor antiga, o streaming duplex abre novas possibilidades para aplicações em tempo real, e o Zstd melhora a performance de transferência de dados.

Se você está avaliando frameworks para backend em Kotlin, vale conferir a [comparação entre Ktor e Spring Boot](/comparacoes/ktor-vs-spring-boot/) para entender qual se encaixa melhor no seu cenário.

Para quem trabalha com outras linguagens no backend, é interessante comparar a abordagem do Ktor com <a href="https://golang.com.br/aprenda/golang-para-backend/" target="_blank" rel="noopener noreferrer" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">frameworks e padrões de Go para backend</a>, que também priorizam simplicidade e performance, ou com o ecossistema de <a href="https://python.dev.br/guias/" target="_blank" rel="noopener noreferrer" onclick="umami.track('portfolio-site-click', { destination: 'python.dev.br' })">Python para APIs com FastAPI</a> — cada linguagem traz suas vantagens dependendo do caso de uso.
