Search code examples
kotlinkotlin-multiplatformktor

How to implement ktor's client in typesafe


I am a kotlin newbie and am getting introduced to ktor by looking at the following page. https://ktor.io/docs/type-safe-request.html#resource_url

So I want to make a type safe request and I have written the following code.

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.resources.*
import io.ktor.client.plugins.resources.Resources

@Resource("/")
class Hoge()

class Client {

    private val client = HttpClient(CIO) {
        install(Resources)
        defaultRequest {
            host = "10.0.2.2"
            port = 8000
            url {
                protocol = URLProtocol.HTTP
            }
        }
    }

    public fun hoge(): String {
        val res = client.get(Hoge())
        return res.bodyAsText()
    }
}

So I received the following error.

None of the following functions can be called with the arguments supplied:
public suspend inline fun HttpClient.get(builder: HttpRequestBuilder): HttpResponse defined in io.ktor.client.request
public suspend inline fun HttpClient.get(block: HttpRequestBuilder.() -> Unit): HttpResponse defined in io.ktor.client.request
public suspend inline fun HttpClient.get(url: Url, block: HttpRequestBuilder.() -> Unit = ...): HttpResponse defined in io.ktor.client.request
public suspend fun HttpClient.get(url: URL, block: HttpRequestBuilder.() -> Unit = ...): HttpResponse defined in io.ktor.client.request
public suspend inline fun HttpClient.get(urlString: String, block: HttpRequestBuilder.() -> Unit = ...): HttpResponse defined in io.ktor.client.request

I implemented it as per the official page, but I am getting the error and I don't know how to solve it. I am looking forward to your answer.


Solution

  • You need to import this extension function:

    io.ktor.client.plugins.resources.get
    

    You also need to be calling client.get() inside of a suspending function. Either make hoge() a suspend fun or introduce some coroutine context. Here is a version of your code that compiles for me. I've commented the fixes and modified it slightly to follow kotlin convention.

    import io.ktor.client.*
    import io.ktor.client.engine.cio.*
    import io.ktor.client.plugins.*
    // this import is what imports the extension functions you need
    import io.ktor.client.plugins.resources.*
    import io.ktor.client.plugins.resources.Resources
    import io.ktor.client.statement.*
    import io.ktor.http.*
    import io.ktor.resources.*
    
    @Resource("/")
    class Hoge
    
    class Client {
        private val client = HttpClient(CIO) {
            install(Resources)
            defaultRequest {
                host = "10.0.2.2"
                port = 8000
                url {
                    protocol = URLProtocol.HTTP
                }
            }
        }
    
        // you need to use a suspend function to call ktor client methods
        suspend fun hoge(): String {
            val res = client.get(Hoge())
            return res.bodyAsText()
        }
    }