Ktor es un cliente HTTP asíncrono y un framework de servidor para Kotlin que admite el desarrollo multiplataforma. La biblioteca está construida sobre corrutinas de Kotlin y funciona en JVM, iOS, Android, JS y Native. Según el repositorio de Ktor en GitHub, el proyecto es desarrollado activamente por el equipo de JetBrains. Ktor ofrece una arquitectura modular con un sistema de complementos para la configuración flexible de conexiones HTTP.
Puntos clave
Ktor es un framework para crear clientes y servidores HTTP en Kotlin, desarrollado por JetBrains. A diferencia de las bibliotecas tradicionales, Ktor fue diseñado desde el principio para el desarrollo multiplataforma y funciona en todas las plataformas compatibles con Kotlin.
Ktor utiliza un enfoque de middleware, inspirado en la arquitectura de Kodein y Express.js. Cada solicitud pasa a través de un pipeline de funciones handler que pueden modificar la solicitud y la respuesta. Esto proporciona una flexibilidad que no está disponible en bibliotecas con una arquitectura rígida basada en anotaciones.
La versión actual Ktor 3.0 incluye soporte para Kotlin 2.0, el compilador K2 y un nuevo motor CIO (Coroutine I/O) con rendimiento mejorado. La biblioteca se distribuye bajo la licencia Apache 2.0 y está disponible para uso comercial sin restricciones.
La parte del cliente de Ktor está completamente construida sobre corrutinas de Kotlin, lo que proporciona una ejecución asíncrona eficiente de solicitudes sin bloquear hilos. La parte del servidor permite crear servidores HTTP con enrutamiento, manejo de solicitudes y conexiones WebSocket.
Ktor utiliza una arquitectura de complementos: todas las funciones adicionales (logging, serialización, autenticación) se conectan a través de complementos. Esto hace que la biblioteca sea modular y permite conectar solo los componentes necesarios, reduciendo el tamaño de la aplicación final.
Gracias a una API unificada en todas las plataformas, el desarrollador no necesita aprender diferentes clientes HTTP para iOS y Android. En un proyecto multiplataforma, el código de la capa de red es completamente compartido, y la implementación específica de la plataforma está oculta detrás del motor HttpClient. Esto reduce el tiempo de desarrollo y disminuye la cantidad de errores relacionados con las diferencias entre plataformas.
Ktor proporciona un conjunto de funciones que lo convierten en una opción atractiva para proyectos Kotlin modernos, especialmente los multiplataforma.
Ktor funciona en JVM, Android, iOS, macOS, Windows, Linux, JavaScript y Wasm. El mismo código de cliente HTTP se ejecuta en todas las plataformas sin cambios. Esta es una ventaja clave sobre las bibliotecas vinculadas a OkHttp o URLSession.
Las corrutinas de Kotlin proporcionan asincronía natural sin callbacks. Cada solicitud es una función suspend que se puede llamar desde cualquier corrutina. Ktor admite streaming de respuestas a través de Flow, lo que es conveniente para conexiones largas y WebSocket.
Los complementos de Ktor se conectan a través de un bloque install y se configuran por separado. Complementos principales: ContentNegotiation para serialización, Logging para logging, Auth para autenticación y WebSockets para comunicación bidireccional. Cada complemento se puede habilitar o deshabilitar de forma independiente.
El manejo de errores en Ktor se basa en excepciones. La clase ClientRequestException se lanza para códigos 4xx, ServerResponseException para 5xx e IOException para fallos de red. Los tiempos de espera se configuran a través del complemento HttpTimeout, que establece el tiempo de espera de conexión, lectura y escritura. Para reintentos se utiliza el complemento Retry con configuración del número de intentos y retardo.
Ktor utiliza una arquitectura de pipeline donde cada solicitud pasa a través de una cadena de handlers. El cliente crea una configuración de HttpClient con complementos instalados, y cada llamada a get o post pasa a través de los complementos en el orden en que se conectaron.
El objeto HttpClient se crea con un motor específico de la plataforma: CIO para JVM y Android, Darwin para iOS y macOS, OkHttp para compatibilidad con Android, Js para navegador. El motor se puede seleccionar explícitamente o dejar la elección automática. Cada solicitud devuelve un HttpResponse que contiene el cuerpo de la respuesta, los encabezados y el estado.
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}
suspend fun fetchUsers(): List<User> {
return client.get("https://api.example.com/users").body()
}
La instalación de Ktor se realiza mediante Gradle o Maven. Para proyectos multiplataforma, las dependencias se especifican en sourceSets para cada destino. Ktor se distribuye a través de Maven Central.
En build.gradle.kts, agregue la dependencia ktor-client-core para el código común y un motor para la plataforma específica. La versión de Ktor se establece a través de una variable en gradle.properties. Ktor 3.x requiere Kotlin 2.0+ y admite el compilador K2.
val ktorVersion = "3.0.3"
dependencies {
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
}
Para iOS, se utiliza el motor Darwin, que envuelve el URLSession nativo. En Kotlin Multiplatform, esto proporciona el máximo rendimiento e integración con los mecanismos de caché del sistema iOS. El motor se agrega como una dependencia separada en el sourceSet de iOS.
Una característica importante de Ktor es el soporte de diferentes formatos de serialización a través de ContentNegotiation. Además de JSON, el complemento admite Protobuf, CBOR, XML y formatos personalizados. Para la serialización se utilizan las bibliotecas kotlinx.serialization o Jackson, y el desarrollador puede cambiar entre ellas sin modificar el código de las solicitudes.
Los ejemplos a continuación demuestran escenarios típicos de trabajo con el cliente Ktor: una solicitud GET básica, envío de datos y trabajo con código multiplataforma.
Una solicitud GET simple con deserialización automática de la respuesta en una clase data. Ktor utiliza el complemento ContentNegotiation con kotlinx.serialization para convertir JSON en objetos. El código resulta conciso y type-safe.
@Serializable
data class Post(
val id: Int,
val title: String,
val body: String
)
suspend fun getPosts(): List<Post> {
val response = client.get("https://jsonplaceholder.typicode.com/posts")
return response.body()
}
Una solicitud POST en Ktor envía una clase data como cuerpo JSON mediante el método post con contentType y setBody. El complemento ContentNegotiation serializa automáticamente el objeto en una cadena JSON. La respuesta se puede procesar de forma síncrona o asíncrona.
suspend fun createPost(): Post {
val newPost = Post(
id = 0,
title = "Nueva publicación",
body = "Contenido de la publicación"
)
val response = client.post("https://jsonplaceholder.typicode.com/posts") {
contentType(ContentType.Application.Json)
setBody(newPost)
}
return response.body()
}
El método submitFormWithBinaryData en Ktor permite enviar archivos y formularios en formato multipart. Ktor divide automáticamente los datos en partes y agrega encabezados. Para rastrear el progreso se utiliza onUpload, que recibe los bytes de datos enviados.
suspend fun uploadFile(fileBytes: ByteArray) {
client.submitFormWithBinaryData(
url = "https://api.example.com/upload",
formData = formData {
append("file", fileBytes, Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=\"photo.png\"")
})
}
)
}
La elección entre Ktor y Retrofit depende de la arquitectura del proyecto y los requisitos de multiplataforma. Retrofit sigue siendo el estándar para proyectos solo Android, mientras que Ktor es la mejor opción para Kotlin Multiplatform.
Ktor también proporciona soporte integrado para WebSocket y SSE (Server-Sent Events), lo que lo hace conveniente para aplicaciones en tiempo real. Retrofit no admite WebSocket directamente; se requiere una biblioteca OkHttp WebSocket separada. Ktor también es más fácil de configurar para diferentes entornos gracias a su sistema de complementos, donde cada complemento es responsable de una función.
El complemento Auth de Ktor admite autenticación básica, tokens Bearer, Digest y OAuth2. La configuración de autenticación se realiza de forma declarativa: el desarrollador especifica el proveedor, la fuente del token y el ámbito. Ktor agrega automáticamente encabezados de autenticación a las solicitudes y puede renovar el token cuando expira.
Si un proyecto utiliza Kotlin Multiplatform con código compartido en iOS y Android, Ktor es la única opción que funciona en ambas plataformas sin capas adicionales. Retrofit está estrechamente vinculado a OkHttp y JVM, lo que lo hace inadecuado para iOS.
Para proyectos solo Android, Retrofit proporciona una API más madura, una mayor cantidad de convertidores e interceptores OkHttp. Ktor también funciona en este escenario, pero su ecosistema de complementos es menos extenso. Ambas bibliotecas admiten corrutinas y ofrecen un rendimiento comparable.
| Criterio | Ktor | Retrofit |
|---|---|---|
| Multiplataforma | iOS, Android, JVM, JS, Native | Solo JVM y Android |
| Motor HTTP | CIO, Darwin, OkHttp, Js | OkHttp |
| Convertidores | kotlinx.serialization, Jackson | Gson, Moshi, Jackson, Protobuf |
| Arquitectura | Pipeline con complementos | Anotaciones con generación de código |
| Desarrollador | JetBrains | Square |
Preguntas frecuentes
Ktor es un cliente HTTP multiplataforma sobre corrutinas de JetBrains. Retrofit es una biblioteca de Android de Square basada en OkHttp. Ktor funciona en iOS, Android, JS y Native, mientras que Retrofit solo funciona en JVM.
Sí, Ktor admite iOS a través del motor Darwin, que utiliza URLSession nativo. Esto proporciona el máximo rendimiento y un funcionamiento correcto con la caché del sistema iOS. El código del cliente sigue siendo compartido entre plataformas.
Ktor admite los motores: CIO (JVM/Android), Darwin (iOS/macOS), OkHttp (Android), Js (navegador), Jetty, Netty, Tomcat (servidor). El motor se puede seleccionar explícitamente o dejar la selección automática por defecto.
Sí, Ktor tiene soporte integrado para WebSocket tanto en el cliente como en el servidor. Para el cliente se utiliza el complemento WebSockets, que permite establecer una conexión bidireccional e intercambiar mensajes en tiempo real.
Los errores se manejan mediante try-catch alrededor de las llamadas suspend. Ktor lanza ClientRequestException para 4xx, ServerResponseException para 5xx e IOException para errores de red. Se recomienda usar el tipo Result para unificar.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también