Nathan Kleinschmidt
04/09/2022, 7:50 PM@Serializable
sealed class Response(
@Contextual
val statusCode: HttpStatusCode = HttpStatusCode.OK
) {
@Serializable
data class SuccessResponse<T>(
val data : T? = null,
val message : String? = null
) : Response()
@Serializable
data class ErrorResponse<T>(
val exception : T? = null,
val message : String? = null
) : Response()
}
However it fails to serialize and I get runtime errors.
If I attempt to convert the response to Json using call.respond(statusCode, Json.encodeToString(result))
then I get:
kotlinx.serialization.SerializationException: Class 'String' is not registered for polymorphic serialization in the scope of 'Any'.
Mark the base class as 'sealed' or register the serializer explicitly.
If I don’t and just attempt to call call.respond(statusCode, result)
, then I get this error instead:
kotlinx.serialization.SerializationException: Serializer for class 'ErrorResponse' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
Not sure if this is an issue with how I am using serialization, or if this is even the recommended way of dealing with responses?George
04/10/2022, 7:44 AMdata: Any
, error :Error
Nathan Kleinschmidt
04/10/2022, 1:57 PMval result = Repository.myMethod(request)
call.respond(result.statusCode, Json.encodeToString(result))
I am using Ktor 2.0, and serialization is configured as a plugin:
fun Application.configureSerialization() {
install(ContentNegotiation) {
json()
}
}
What other configuration does serialization need?George
04/10/2022, 2:04 PMval responseModule = SerializersModule {
polymorphic(Response::class) {
subclass(SuccessResponse.serializer(PolymorphicSerializer(Any::class)))
}
}
refering directly this example in docs: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#polymorphism-and-generic-classes
In your example something like this could be ok :
val responseModule = SerializersModule {
polymorphic(Response::class) {
subclass(OkResponse.serializer(PolymorphicSerializer(Any::class)))
}
subclass(ErrorResponse.serializer(PolymorphicSerializer(Any::class)))
}
}
I have not tested the code, but i hope you get the ideaNathan Kleinschmidt
04/10/2022, 2:50 PMval module = SerializersModule {
polymorphic(Response::class) {
subclass(Response.SuccessResponse.serializer(PolymorphicSerializer(Any::class)))
subclass(Response.ErrorResponse.serializer(PolymorphicSerializer(Any::class)))
}
}
val format = Json { serializersModule = module }
call.respond(result.statusCode, format.encodeToString(result))
results in
Class 'String' is not registered for polymorphic serialization in the scope of 'Any'.
Mark the base class as 'sealed' or register the serializer explicitly.
I see in one of the example that they also include an extension function in the SerializersModule block:
val module = SerializersModule {
fun PolymorphicModuleBuilder<Project>.registerProjectSubclasses() {
subclass(OwnedProject::class)
}
polymorphic {
...
}
}
but that also does not work, same error message.George
04/10/2022, 2:52 PM/**
* A [String] serializer as an object, and workaround for
* [kotlinx.serialization-1252](<https://github.com/Kotlin/kotlinx.serialization/issues/1252>).
*/
internal object StringSerializer : KSerializer<String> {
@Serializable
@SerialName("String")
data class StringSurrogate(val value: String)
override val descriptor: SerialDescriptor = StringSurrogate.serializer().descriptor
override fun serialize(encoder: Encoder, value: String) {
StringSurrogate.serializer().serialize(encoder, StringSurrogate(value))
}
override fun deserialize(decoder: Decoder): String {
return decoder.decodeSerializableValue(StringSurrogate.serializer()).value
}
}
private val module = SerializersModule {
polymorphic(Response::class) {
subclass(Response.SuccessResponse.serializer(PolymorphicSerializer(Any::class)))
subclass(Response.ErrorResponse.serializer(PolymorphicSerializer(Any::class)))
polymorphic(Any::class) {
subclass(StringSerializer::class, StringSerializer.serializer)
}
}
}
Nathan Kleinschmidt
04/10/2022, 3:07 PMGeorge
04/10/2022, 3:23 PMAny
Type as value). The code worked?Nathan Kleinschmidt
04/11/2022, 1:04 AMGeorge
04/11/2022, 4:46 AM