alllex
07/27/2022, 7:58 AMimport kotlinx.serialization.*
import kotlinx.serialization.json.Json
@Serializable
sealed class ApiResponse<T> {
@Serializable
@SerialName("result")
data class Ok<T>(val result: T) : ApiResponse<T>()
@Serializable
@SerialName("error")
data class Error<T>(val error: ErrorResponse) : ApiResponse<T>()
}
@Serializable
data class VersionResponse(val version: String)
@Serializable
data class ErrorResponse(val description: String)
fun main() {
val data: ApiResponse<VersionResponse> = ApiResponse.Ok(VersionResponse("v42"))
println(Json.encodeToString(data)) // prints {"type":"result","result":{"version":"v42"}}
}
The last line mentions the result I want to achieve: ApiResponse
is discriminated using type
, and the result
field is just serialized as it is.
However, running this with Kotlin 1.7.10 and kotlinx.serialization 1.3.3 (json jvm) produces this error:
Exception in thread "main" kotlinx.serialization.SerializationException: Class 'VersionResponse' is not registered for polymorphic serialization in the scope of 'Any'.
Mark the base class as 'sealed' or register the serializer explicitly.
at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:102)
Could you please help figuring this out?
I tried in many ways to configure polymorphic serialization, but none of them worked.rocketraman
07/27/2022, 3:08 PMval format = Json {
serializersModule = SerializersModule {
polymorphic(Any::class) {
subclass(VersionResponse::class)
}
}
}
val data: ApiResponse<VersionResponse> = ApiResponse.Ok(VersionResponse("v42"))
println(format.encodeToString(data)) // prints {"type":"result","result":{"version":"v42"}}
rocketraman
07/27/2022, 3:09 PMalllex
07/27/2022, 8:00 PMseralizersModule
. However, what it prints is not exactly what I need:
{
"type": "result",
"result": {
"type": "VersionResponse",
"version": "v42"
}
}
As you can see, it adds type
inside result
as well.rocketraman
07/27/2022, 8:03 PMrocketraman
07/27/2022, 8:07 PMSerializer