Kotlin y las APIs: los tres pilares del desarrollo moderno
\n\n¿Alguna vez te has preguntado por qué unas aplicaciones vuelan y otras se quedan lentas incluso en los dispositivos insignia? El secreto a menudo no está en el hardware, sino en cómo se comunican con el servidor. Si programas en Kotlin —ya sea un backend con Ktor o una aplicación Android— tarde o temprano te enfrentarás a la elección: ¿REST, GraphQL o gRPC?
\n\nEn PythonLib nos encanta desglosar las tecnologías hasta el último detalle. Hoy analizaremos a fondo tres enfoques para trabajar con APIs en Kotlin. Sin rodeos: solo código, comparaciones y casos reales. ¡Allá vamos!
\n\nAPI REST en Kotlin: un clásico que nunca pasa de moda
\n\nREST es como un traje negro: apropiado en todas partes, simple y comprensible. En Kotlin, hay dos actores principales para REST: Ktor (para el lado del servidor) y Retrofit (para el lado del cliente).
\n\nServidor con Ktor: escribe una API en 5 minutos
\n\nKtor es un framework de JetBrains, creado específicamente para Kotlin. Es asíncrono, ligero y no impone dependencias innecesarias.
\n\n// build.gradle.kts\nimplementation("io.ktor:ktor-server-netty:2.3.7")\nimplementation("io.ktor:ktor-server-content-negotiation:2.3.7")\nimplementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")\n\nY ahora el servidor en sí:
\n\nimport io.ktor.server.engine.*\nimport io.ktor.server.netty.*\nimport io.ktor.server.routing.*\nimport io.ktor.server.response.*\nimport io.ktor.serialization.kotlinx.json.*\nimport io.ktor.server.plugins.contentnegotiation.*\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class User(val id: Int, val name: String, val email: String)\n\nfun main() {\n embeddedServer(Netty, port = 8080) {\n install(ContentNegotiation) {\n json()\n }\n routing {\n get("/api/users") {\n val users = listOf(\n User(1, "Ana", "anna@example.com"),\n User(2, "Boris", "boris@example.com")\n )\n call.respond(users)\n }\n get("/api/users/{id}") {\n val id = call.parameters["id"]?.toIntOrNull()\n if (id != null) {\n call.respond(User(id, "Test", "test@example.com"))\n } else {\n call.respondText("ID inválido", status = io.ktor.http.HttpStatusCode.BadRequest)\n }\n }\n }\n }.start(wait = true)\n}\n\nEste código es una API REST en Kotlin completa con dos endpoints. Ktor serializa los datos a JSON automáticamente gracias a kotlinx.serialization.
Cliente con Retrofit: conéctate a cualquier API
\n\nRetrofit es el estándar de facto para el desarrollo Android. Con Kotlin funciona perfectamente gracias a las corrutinas.
\n\n// build.gradle.kts\nimplementation("com.squareup.retrofit2:retrofit:2.9.0")\nimplementation("com.squareup.retrofit2:converter-gson:2.9.0")\nimplementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")\n\nDeclaramos la interfaz:
\n\ninterface ApiService {\n @GET("users")\n suspend fun getUsers(): List<User>\n\n @GET("users/{id}")\n suspend fun getUser(@Path("id") userId: Int): User\n\n @POST("users")\n suspend fun createUser(@Body user: User): User\n}\n\nCreamos el cliente y hacemos la solicitud:
\n\nval retrofit = Retrofit.Builder()\n .baseUrl("https://api.example.com/")\n .addConverterFactory(GsonConverterFactory.create())\n .build()\n\nval service = retrofit.create(ApiService::class.java)\n\n// En una corrutina\nGlobalScope.launch {\n val users = service.getUsers()\n println(users)\n}\n\nVentajas de REST: simplicidad, almacenamiento en caché a través de HTTP, comunidad enorme.
\nDesventajas: sobrecarga y subcarga de datos (over-fetching y under-fetching): a menudo obtienes más o menos de lo que necesitas.