https://kotlinlang.org logo
#ktor
Title
# ktor
f

fbodr

06/30/2022, 12:28 PM
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

hfhbd

06/30/2022, 2:27 PM
I think it is not yet implemented: https://github.com/ktorio/ktor/pull/3000#discussion_r888923077 I will work on this PR soon
f

fbodr

06/30/2022, 2:29 PM
I se … thank you 🙂 .. I ll follow the github issue then 👍
a

Aleksei Tirman [JB]

06/30/2022, 3:21 PM
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

hfhbd

06/30/2022, 7:42 PM
@Aleksei Tirman [JB] Some corner cases are not possible with contextual. I will add the overload for regular request in the PR too.
4 Views