Ktor Client in Kotlin Multiplatform

Mehedi Hassan Piash
3 min readJul 28, 2024

--

Kotlin Multiplatform (KMP) allows you to write code that can be shared across multiple platforms, including Android, iOS, desktop and the web. One of the libraries that make KMP even more powerful is Ktor, a framework for building asynchronous servers and clients in connected systems. In this blog post, we’ll walk through setting up a Ktor client in a KMP project and making a sample HTTP request.

ktor client

Setting Up the Ktor Client

First, let’s look at the code snippet that configures the Ktor client:

val client = HttpClient {
defaultRequest {
url {
takeFrom("https://api.themoviedb.org/") // Base url
parameters.append("api_key", "59cd6896d8432")
}
}
expectSuccess = true
install(HttpTimeout) {
val timeout = 30000L
connectTimeoutMillis = timeout
requestTimeoutMillis = timeout
socketTimeoutMillis = timeout
}
install(Logging) {
logger = Logger.DEFAULT
level = LogLevel.HEADERS
logger = object : Logger {
override fun log(message: String) {
println(message)
}
}
}
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}

Let’s break down what each part of this configuration does.

Default Request Configuration

The defaultRequest block sets up default parameters for all requests made by this client:

defaultRequest {
url {
takeFrom("https://api.themoviedb.org/") // Base url
parameters.append("api_key", "59cd6896d8432")
}
}

Here, we’re specifying a base URL and appending an API key to every request. This is useful for APIs that require authentication or other constant query parameters.

Timeout Configuration

Next, we configure the timeouts for the client:

install(HttpTimeout) {
val timeout = 30000L
connectTimeoutMillis = timeout
requestTimeoutMillis = timeout
socketTimeoutMillis = timeout
}

We set a 30-second timeout for connecting, requesting, and socket operations. This ensures that our client doesn’t hang indefinitely.

Logging Configuration

The Logging feature helps us log HTTP requests and responses:

install(Logging) {
logger = Logger.DEFAULT
level = LogLevel.HEADERS
logger = object : Logger {
override fun log(message: String) {
println(message)
}
}
}

Here, we log the headers of the requests and responses. The custom logger prints these logs to the console.

Content Negotiation

Finally, we configure content negotiation to handle JSON data:

install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}

This tells the client to use JSON for content negotiation and to ignore unknown keys in the JSON response, making the client more resilient to changes in the API.

Using the Ktor Client

Once the client is configured, you can use it to make HTTP requests. Here’s an example of making a GET request to fetch data for a specific person:

suspend fun fetchPersonData(personId: String): Person {
return client.get {
url {
encodedPath = "3/person/$personId"
}
}.body()
}

In this function, we make a GET request to the /3/person/{personId} endpoint. The encodedPath specifies the endpoint, and the personId is dynamically included in the URL. The body() function is used to parse the response into a Person object.

Example Usage

You can call the fetchPersonData function in a coroutine to get the data for a specific person:

fun main() = runBlocking {
val personId = "12345"
val personData = fetchPersonData(personId)
println(personData)
}

In this example, we use runBlocking to start a coroutine, fetch the data for a person with ID 12345, and print the result.

Conclusion

Configuring a Ktor client in a Kotlin Multiplatform project is straightforward and highly customizable. By setting up default requests, timeouts, logging, and content negotiation, you can ensure your HTTP client is robust and efficient. Making requests and handling responses is seamless, allowing you to build powerful and responsive applications. Happy coding!

Ref:
https://piashcse.blogspot.com/2024/07/ktor-client-in-kotlin-multiplatform.html

--

--

Mehedi Hassan Piash
Mehedi Hassan Piash

Written by Mehedi Hassan Piash

Sr. Software Engineer | Android | iOS | KMP | Jetpack Compose | React-Native.

No responses yet