functionaldude
03/31/2022, 3:17 PMJsonFeature
. I have the following class structure:
@Serializable
sealed class Base {
@Serializable
class Child: Base()
}
When I do a post request with Child()
as body, the class discriminator is missing (the body is just {}
). I figured out that `Child`’s serializer is used, if I use `Base`’s serializer then the class discriminator is there:
val payload = Base.Child()
val payloadString1 = kotlinxSerializer.encodeToString(Base.serializer(), payload) // payloadString1 = "{"@class": "com.example.Base.Child"}"
val payloadString2 = kotlinxSerializer.encodeToString(Base.Child.serializer(), payload) // payloadString2 = "{}"
The problem is, I can’t find a way to force the Ktor client to use the sealed class’s serializer. Is this a bug or the intended behaviour? And if this is the intended behaviour then how can I tell the Ktor client to use a different serializer?Aleksei Tirman [JB]
03/31/2022, 4:10 PMBase
class serializer for Child
objects. Here is an example:
import io.ktor.client.HttpClient
import io.ktor.client.engine.apache.*
import io.ktor.client.features.json.*
import io.ktor.client.features.json.serializer.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.serialization.modules.SerializersModule
suspend fun main() {
val module = SerializersModule {
contextual(Base.Child::class) {
Base.serializer()
}
}
val client = HttpClient(Apache) {
install(JsonFeature) {
serializer = KotlinxSerializer(kotlinx.serialization.json.Json {
serializersModule = module
})
}
}
val r = <http://client.post|client.post><String>("<https://httpbin.org/post>") {
body = Base.Child()
contentType(ContentType.Application.Json)
}
println(r)
}
@kotlinx.serialization.Serializable
sealed class Base {
@kotlinx.serialization.Serializable
class Child: Base()
}
Nathan Kleinschmidt
04/05/2022, 10:40 PMmodule
and client
in a real project? Would it be in the same file as the sealed class Base
? Seems like a lot of boilerplate to be in the main function.