hi all. For those using kotlinx-serialization with...
# ktor
f
hi all. For those using kotlinx-serialization with ktor, how did you manage to use @Serializer custom serializers with content-negotiation plugin ? i have some classes that are auto generated (so I cannot annotate them with @Serializable), but I cannot find a way for ktor to use the custom serializer
h
I think it is not yet implemented: https://github.com/ktorio/ktor/pull/3000#discussion_r888923077 I will work on this PR soon
f
I se … thank you 🙂 .. I ll follow the github issue then 👍
a
You can register a contextual serializer for a generated class via a Serializer Module. Here is an example:
Copy code
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule

fun main() {
    embeddedServer(Netty, port = 5555) {
        install(ContentNegotiation) {
            json(Json {
                serializersModule = SerializersModule {
                    contextual(MyClass::class, MyClassSerializer)
                }
            })
        }

        routing {
            post("/") {
                val x = call.receive<MyClass>()
                println(x)
                call.respondText { "OK" }
            }
        }
    }.start(true)
}

class MyClass

object MyClassSerializer: KSerializer<MyClass> {
    override val descriptor: SerialDescriptor
        get() = PrimitiveSerialDescriptor("MyClass", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): MyClass {
        return MyClass()
    }

    override fun serialize(encoder: Encoder, value: MyClass) {
        encoder.encodeString("MyClass")
    }
}
h
@Aleksei Tirman [JB] Some corner cases are not possible with contextual. I will add the overload for regular request in the PR too.