I'm trying to deserialize a data class to be sent through a WebSocket with the Kotlinx.serialization library using Ktor, but I'm having some issues, the serializer just deserializes the first value of the data class. I'm using Kmongo for the connection with the database so I'm using the @BsonId annotation for making MongoDb that that property is the id.
I leave here the data class.
@Serializable
data class Kayak(
@Serializable(ObjectIdSerializer::class) @BsonId val id: ObjectId = ObjectId(),
val available: Boolean = true,
val type: TypeOfKayak = TypeOfKayak.Single,
val reservesIds: List<String> = emptyList()
)
As the serializer doesn't know how to serialize and deserialize the ObjectId data type I've made it by myself and it's the next:
fun String.toObjectId(): ObjectId = ObjectId(this)
object ObjectIdSerializer : KSerializer<ObjectId> {
override val descriptor = PrimitiveSerialDescriptor("ObjectId", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: ObjectId) {
encoder.encodeString(value.toHexString())
}
override fun deserialize(decoder: Decoder): ObjectId {
val stringValue = decoder.decodeString()
try {
return ObjectId(stringValue)
} catch (e: IllegalArgumentException) {
throw SerializationException("Failed to deserialize ObjectId: $stringValue", e)
}
}
}
The expected output would be like this:
[
{
"id": "648b2fa450b8031dadaf62a8",
"available": true,
"type": "Single",
"reservesIds": [
"abc123",
"def456"
]
},
{
"id": "648b2fa450b8031dadaf62a9",
"available": false,
"type": "Double",
"reservesIds": [
"xyz789"
]
}
]
but instead it's like this:
{
"id": "648b2fa450b8031dadaf62a8"
}
I tried by using the next things:
private val json = Json {
prettyPrint = true
ignoreUnknownKeys = true
}
val message = json.encodeToString(kayaksDb.getAllKayaks())
val message = json.encodeToString<List<Kayak>>(kayaksDb.getAllKayaks(), ListSerializer(Kayak.serializer()))
Anyways It's strange because when I just use in an endpoint the call.respond()
function it works well, I leave here an example:
get<KayaksRoutes> {
call.respond(kayaksDataSource.getAllKayaks())
}
the output is the next:
[
{
"id": "648b2fa450b8031dadaf62a8",
"available": true,
"type": "Single",
"reservesIds": []
}
]
so I think I'm doing something bad at the moment of sending the data/parsing it to the WebSocket.
Thank you guys for the help!