Kotlin Multiplatform Networking Data Ktor

Andrea
3 min readMay 18, 2024

Creating any application always revolve around on storing and retrieving data. A simple app such as Weather App, News App, the core task is to retrieve data from its source (API) and display it to user in aesthetic way.

In this writing, I will try to documented the most common method to fetch data from API using Ktor. The purpose using Ktor for Kotlin Multiplatform, since using Kotlin Multiplatform can be deploy in various platform device using only one source code.

Ktor is an asynchronous framework for creating microservices, web applications and more. Written in Kotlin from the ground up.

Dependency library :

ktor = "2.3.9"

ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
// inside build.gradle.kts
sourceSets {
val desktopMain by getting {
dependencies {
implementation(libs.ktor.client.cio)
}
}

val androidMain by getting {
dependencies {
implementation(libs.compose.ui.tooling.preview)
implementation(libs.androidx.activity.compose)
implementation(libs.ktor.client.cio)
implementation ("com.google.accompanist:accompanist-systemuicontroller:0.27.0")
implementation("androidx.startup:startup-runtime:1.1.1")
}
}

val commonMain by getting {
dependencies {
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.client.logging)
implementation(libs.ktor.serialization.kotlinx.json)
}
}

val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
dependencies {
implementation(libs.ktor.client.darwin)
}
}
}
}

One of the common method to get data from API is GET request

  1. Create HttpClient
    A multiplatform asynchronous HTTP client, which allows you to make requests and handle responses, extend its functionality with plugins, such as authentication, JSON serialization, and so on.
val defaultHttpClient = HttpClient {
install(ContentNegotiation) {
json(Json { ignoreUnknownKeys = true }) }

install(Logging) { logger = Logger.SIMPLE }

defaultRequest {
url {
host = "api.openweathermap.org"
protocol = URLProtocol.HTTPS
parameters.append("lat", "45.5019")
parameters.append("lon", "-73.5674")
parameters.append("exclude", "minutely" )
parameters.append("appid", API_KEY)
}
}
}

Above hattpClient will fetch data from url : “https://api.openweathermap.org/data/3.0/onecall?lat=45.5019&lon=-73.5674&exclude=minutely&appid=${API_KEY}"

We can also put on some parameter on the client by building url. This code bellow will create same url except that the latitude and longitude become parameter inside function, the function will return Http Client

private fun buildUrl(lat: Double, lon: Double): HttpClient =
HttpClient() {
install(ContentNegotiation) {
json(Json { ignoreUnknownKeys = true })
}

install(Logging) {
logger = Logger.SIMPLE
level = LogLevel.BODY
}

defaultRequest {
url {
host = "api.openweathermap.org"
protocol = URLProtocol.HTTPS
parameters.append("lat", lat.toString())
parameters.append("lon", lon.toString())
parameters.append("exclude", "minutely" )
parameters.append("appid", API_KEY)
}
}
}

2. Make GET request
After setting up the client, you can make HTTP requests. The main way of making HTTP requests is the request function that can take a URL as a parameter. Inside this function, you can configure various request parameters:

  • Specify an HTTP method, such as GET, POST, PUT, DELETE, HEAD, OPTION, or PATCH.
  • Specify a URL as a string or configure URL components (a domain, a path, query parameters, etc.) separately.
  • Add headers and cookies.
  • Set the body of a request, for example, a plain text, a data object, or form parameters.

For GET request, HttpClient simply call GET request adding some additional Url Path

suspend fun getWeatherApiDataFrLonLat(latitude: Double, longitude:Double): Result<WeatherAPIResponse> =
buildUrl(latitude, longitude).get { url {
path("data/3.0/onecall")} }

3. Make POST request

Making POST request will be similar with GET request, except that we adding some content inside the request

private suspend fun requestCurrentLocation(): io.ktor.client.statement.HttpResponse =
client.post {
url(urlPost)
contentType(ContentType.Application.Json)
setBody(
LocationRequest(
macAddress = InetAddress.getLocalHost().hostAddress,
signalStrength = -35,
signalToNoiseRatio = 0,
channel = 11,
age = 0
)
)
}

Hopefully this simple article can help us on using Ktor for networking job. More reference here.

Also please checkout & comment my Compose Multiplattform app on my github.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Andrea
Andrea

No responses yet

Write a response