I'm migrating from retrofit to ktor client, and as...
# ktor
m
I'm migrating from retrofit to ktor client, and as a part of the migration I want to wrap the returned
kotlinx
@Serializable
responses in sealed classes for modeling
Success
&
Error
respectively:
Copy code
val result: ApiResult<List<Foo>> = client.get(url).body()
when(result) {
	is ApiResult.Success -> {}
	is ApiResult.Error -> {}
}
I made a ktor plugin to transform the response to my defined
ApiResult
sealed interface like this:
Copy code
val plugin = createClientPlugin("ApiResultWrapper") {  
    transformResponseBody { response, _, _ ->  
        if (response.status.isSuccess()) {  
            try {  
                ApiResult.Success(response.body())  
            } catch (e: Exception) {  
                ApiResult.Error(code = null, throwable = e)  
            }  
        } else {  
            ApiResult.Error(code = response.status.value, throwable = null)  
        }  
    }  
}
but, Apparently,
response.body()
returns
HttpResponse[/*request url*/, 200 OK]
instead of deserializing the actual payload of the response. I've been following the docs, some samples, and also did some searching here in the channel but couldn't find how to solve my problem or which API exactly I need to use? Thanks in advance.
a
Can you share the definition of the
ApiResult
class?
m
Sure, here it is:
Copy code
sealed interface ApiResult<out T : Any> {
    data class Success<out T : Any>(val data: T) : ApiResult<T>
    data class Error(val code: Int?, val throwable: Throwable? = null) : ApiResult<Nothing>
}
Follow-up: I think my problem is actually that I can't get a
KSerializer
from
typeInfo
. I tried this:
Copy code
jsonInstance.decodeFromString(typeInfo.ofInnerClassParameter().type.serializer(), response.bodyAsText())
where
ofInnerClassParameter()
is:
Copy code
fun TypeInfo.ofInnerClassParameter(): TypeInfo {
    val typeProjection = kotlinType?.arguments?.get(0)
    val kType = typeProjection!!.type!!
    return TypeInfo(kType.classifier as KClass<*>, kType.platformType)
}
but I'm getting:
Copy code
kotlinx.serialization.json.internal.JsonDecodingException: Expected class kotlinx.serialization.json.JsonObject as the serialized body of kotlinx.serialization.Polymorphic<List>, but had class kotlinx.serialization.json.JsonArray):
I guess I can't do this in an easy way due to type erasure on JVM.
a
Unfortunately, I couldn't find a way too.