Cliente HTTP en Kotlin: haciendo solicitudes correctamente — nivel avanzado

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cliente HTTP en Kotlin: haciendo solicitudes correctamente — nivel avanzado



Al desarrollar aplicaciones modernas en Kotlin, el trabajo con solicitudes HTTP va mucho más allá de una simple llamada a URL.readText(). A nivel avanzado, es necesario considerar la gestión de conexiones, tiempos de espera, reintentos, registro de actividad, asincronía y un manejo correcto de errores. En este artículo, analizaremos cómo configurar un cliente HTTP en Kotlin para un entorno de producción, utilizando dos bibliotecas populares: OkHttp y Ktor Client. El material está dirigido a desarrolladores que ya conocen los fundamentos de Kotlin y HTTP.



1. Elección de la biblioteca: OkHttp vs Ktor Client

Antes de escribir código, es importante entender la diferencia entre los enfoques. OkHttp es una biblioteca madura y probada de Square, que funciona muy bien junto con Retrofit. Ktor Client es una biblioteca nativa multiplataforma de JetBrains, completamente integrada con las corrutinas de Kotlin. Para proyectos de servidor con Spring Boot, a menudo se elige OkHttp, mientras que para aplicaciones Ktor o proyectos multiplataforma se prefiere Ktor Client.



Analizaremos ambas opciones para que puedas elegir la más adecuada para tu stack tecnológico.



2. Configuración avanzada de OkHttp

La configuración básica de OkHttp es trivial, pero para producción se requiere una configuración más detallada. Veamos cómo crear un cliente Singleton con parámetros personalizados.



import okhttp3.*import java.util.concurrent.TimeUnit

object HttpClientProvider {

private val client: OkHttpClient by lazy { OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .retryOnConnectionFailure(true) .addInterceptor(LoggingInterceptor()) .addInterceptor(RetryInterceptor(maxRetries = 3)) .connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES)) .build() }

fun getClient(): OkHttpClient = client}


2.1 Interceptores personalizados (Interceptors)

Los interceptores son un mecanismo potente para modificar solicitudes y respuestas. A continuación, se muestra un ejemplo de un interceptor de registro y un interceptor para reintentos.



class LoggingInterceptor : Interceptor {    override fun intercept(chain: Interceptor.Chain): Response {        val request = chain.request()        println("--> ${request.method} ${request.url}")        val startTime = System.nanoTime()        val response = chain.proceed(request)        val duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)        println("<-- ${response.code} ${response.message} (${duration}ms)")        return response    }}

class RetryInterceptor(private val maxRetries: Int) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { var retryCount = 0 var response: Response? = null while (retryCount < maxRetries) { try { response = chain.proceed(chain.request()) if (response.isSuccessful) return response } catch (e: Exception) { println("Reintento #${retryCount + 1} falló: ${e.message}") } retryCount++ if (retryCount < maxRetries) Thread.sleep(1000L * retryCount) } return response ?: throw IOException("Máximo de reintentos excedido") }}


2.2 Solicitudes asíncronas con corrutinas

OkHttp admite solicitudes síncronas y asíncronas (basadas en callbacks). Para la integración con corrutinas de Kotlin, utilizamos suspendCancellableCoroutine.



suspend fun makeRequest(url: String): String {    return suspendCancellableCoroutine { continuation ->        val request = Request.Builder().url(url).build()        val call = HttpClientProvider.getClient().newC                

Blogs

Book Recommendations