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

crummy

04/28/2020, 11:28 PM
How do I register a customer serializer for a class using kotlinx serialization in Ktor?
c

crummy

04/28/2020, 11:57 PM
I've followed that, and use it to annotate my data class with
@Serializable(with = LocalDateSerializer::class)
. However, now I'm returning a
Map<LocalDate, foo>
and I don't know how to annotate this. Is there a way to register a serializer so that it's always used for a specific class?
e.g. I can do this with Jackson because I can get access to the object mapper: https://ktor.io/servers/features/content-negotiation/jackson.html
e

edenman

04/29/2020, 12:02 AM
where are you putting
@Serializable(with = LocalDateSerializer::class)
? it should just work if you put it on
LocalDate
afaik
c

crummy

04/29/2020, 12:05 AM
That worked, on a data class. But where do I put it on a
Map<LocalDate, foo>
?
e

edenman

04/29/2020, 12:05 AM
no i’m saying if you put that annotation on the
LocalDate
class itself, you shouldn’t need any annotation on the
Map
c

crummy

04/29/2020, 12:06 AM
LocalDate is a java class, I can't put it on the class itself
e

edenman

04/29/2020, 12:19 AM
ah hm. not 100% sure but you might have to register a serializer for that Map type
c

crummy

04/29/2020, 12:30 AM
turns out you can add an annotation to a type declaration:
Copy code
val timesheets: Map<@Serializable(with = LocalDateSerializer::class)LocalDate, DaySummary>
... but it doesn't seem to help
😮 1
s

Sam Garfinkel

04/29/2020, 3:58 AM
You have a few options: Use a contextual serializer, use the
@Serializable(with=<Class>)
at each instance of the external class, or use
@file:UseSerializers
. I prefer the last solution since it’s a bit more clean imo. Both 2 and 3 only work if the serializer is a singleton or has a no-op constructor, otherwise you’ll need to register a contextual serializer with a
SerialModule
However in your specific use-case I believe you are being effected by this bug https://github.com/Kotlin/kotlinx.serialization/issues/802
Because there’s no concrete serializer defined for Map, the built in serializer (I think) relies on reflection, which doesn’t have a way of locating contextual serializers. The workaround is to reimplement the typeOf serializer function to accept the serialModule as an argument and try to find a contextual serializer for keys/values
The Ktor client is affected by this bug so I assume the same is true for the server
c

crummy

04/29/2020, 4:07 AM
Thanks for the clarification, that makes sense.
s

Sam Garfinkel

04/29/2020, 4:09 AM
Unfortunately the only actual fix is to implement your own JsonSerializer that uses the patched
serializer<T>
implementation that I suggested in that issue.
28 Views