Kotlin und APIs: Die drei Säulen der modernen Entwicklung
\n\nHaben Sie sich jemals gefragt, warum einige Anwendungen fliegen, während andere selbst auf Flaggschiff-Geräten träge sind? Das Geheimnis liegt oft nicht in der Hardware, sondern darin, wie sie mit dem Server kommunizieren. Wenn Sie in Kotlin programmieren – sei es ein Backend mit Ktor oder eine Android-App – werden Sie früher oder später vor der Wahl stehen: REST, GraphQL oder gRPC?
\n\nBei PythonLib lieben wir es, Technologien bis ins kleinste Detail zu verstehen. Heute analysieren wir drei Ansätze für die Arbeit mit APIs auf Kotlin. Kein überflüssiges Geschwafel: nur Code, Vergleiche und reale Anwendungsfälle. Los geht's!
\n\nREST API auf Kotlin: Ein Klassiker, der nie alt wird
\n\nREST ist wie ein schwarzer Anzug: überall passend, einfach und verständlich. In Kotlin gibt es zwei Hauptakteure für REST: Ktor (für die Serverseite) und Retrofit (für die Clientseite).
\n\nServer mit Ktor: API in 5 Minuten schreiben
\n\nKtor ist ein Framework von JetBrains, das speziell für Kotlin entwickelt wurde. Es ist asynchron, leichtgewichtig und zwingt keine unnötigen Abhängigkeiten auf.
\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\nUnd nun der Server selbst:
\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, "Anna", "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("Ungültige ID", status = io.ktor.http.HttpStatusCode.BadRequest)\n }\n }\n }\n }.start(wait = true)\n}\n\nDieser Code ist eine vollwertige REST API auf Kotlin mit zwei Endpunkten. Ktor serialisiert die Daten dank kotlinx.serialization automatisch in JSON.
Client mit Retrofit: Verbindung zu jeder API herstellen
\n\nRetrofit ist der De-facto-Standard für die Android-Entwicklung. Mit Kotlin funktioniert es dank Coroutinen perfekt.
\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\nDeklarieren des Interfaces:
\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\nClient erstellen und Anfrage senden:
\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// In einer Coroutine\nGlobalScope.launch {\n val users = service.getUsers()\n println(users)\n}\n\nVorteile von REST: Einfachheit, Caching über HTTP, riesige Community.
\nNachteile: Over-Fetching und Under-Fetching von Daten – Sie erhalten oft mehr oder weniger als benötigt.