Kotlin e API: os três pilares do desenvolvimento moderno
\n\nVocê já se perguntou por que alguns aplicativos voam enquanto outros travam até mesmo em flagships? O segredo muitas vezes não está no hardware, mas em como eles se comunicam com o servidor. Se você programa em Kotlin — seja um backend com Ktor ou um aplicativo Android — mais cedo ou mais tarde se deparará com a escolha: REST, GraphQL ou gRPC?
\n\nNo PythonLib, adoramos entender as tecnologias nos mínimos detalhes. Hoje vamos detalhar três abordagens para trabalhar com API em Kotlin. Sem enrolação: apenas código, comparação e casos reais. Vamos lá!
\n\nAPI REST em Kotlin: o clássico que nunca envelhece
\n\nREST é como um terno preto: adequado em qualquer lugar, simples e compreensível. Em Kotlin, existem dois principais players para REST: Ktor (para o lado do servidor) e Retrofit (para o lado do cliente).
\n\nServidor com Ktor: escrevendo uma API em 5 minutos
\n\nKtor é um framework da JetBrains, criado especificamente para Kotlin. Ele é assíncrono, leve e não impõe dependências desnecessárias.
\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\nE agora o próprio servidor:
\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", "ana@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, "Teste", "teste@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 é uma API REST completa em Kotlin com dois endpoints. O Ktor serializa os dados em JSON automaticamente graças ao kotlinx.serialization.
Cliente com Retrofit: conectando-se a qualquer API
\n\nRetrofit é o padrão de facto para desenvolvimento Android. Com Kotlin, funciona perfeitamente graças às corrotinas.
\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 a interface:
\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\nCriamos o cliente e fazemos a requisição:
\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// Em uma corrotina\nGlobalScope.launch {\n val users = service.getUsers()\n println(users)\n}\n\nVantagens do REST: simplicidade, cache via HTTP, comunidade enorme.
\nDesvantagens: over-fetching e under-fetching de dados — muitas vezes você recebe mais ou menos do que precisa.