Litote / kmongo

[deprecated] KMongo - a Kotlin toolkit for Mongo
https://litote.org/kmongo/
Apache License 2.0
781 stars 74 forks source link

How to configure kotlinx.serialization Json object for Kmongo? #334

Closed theextremeprogrammer closed 2 years ago

theextremeprogrammer commented 2 years ago

First of all - thank you for the kmongo library and the efforts you put into maintaining it! I am struggling with what feels like it should be a simple use case, so I have a feeling that my understanding has a blind spot and I'm hoping someone might be able to help.

I am utilizing kmongo in a Ktor backend with MongoDB Atlas and it has been working great. Given that Ktor utilizes kotlinx.serialization, I thought it would be best to utilize this for MongoDB/kmongo as well.

After checking the documentation and other issues (such as #218 "Load KMongo Serializers in Kotlinx.Serialization with KTor"), I wasn't able to determine how to configure the Json object for kotlinx.serialization specific to when Kmongo serializes and deserializes objects. Long story short, I am looking at how to handle changes to the schema of these objects and I want to add fields as the schema changes and ensure that the older documents can still be read without any issues. (Ideally, I would like to be able to configure how serialization is handled at the kmongo level separately from how serialization is handled for REST API requests.)

Just as an example, I can configure this for network requests by setting parameters related to how strict or lenient serialization can be as such:

val jsonConfig = Json {
    explicitNulls = false
    ignoreUnknownKeys = true
    // ... as needed
}

... and I can also create a custom serializer for an object as well, though this choice feels like it might be a bit much.

Is there a way to configure how Kmongo serializes and deserializes objects to/from documents when using kotlinx.serialization? Or would it be necessary to create a custom serializer for each object type? Or is there another piece of the puzzle that I am missing?

Thanks for your help! 🙇🏻‍♂️

zigzago commented 2 years ago

Hello,

KMongo uses kbson in order to serialize/deserialize bson (mongo does not use json - so we need bson encoding).

You can update the com.github.jershell.kbson.Configuration object using the configuration var.

https://github.com/Litote/kmongo/blob/2edee31bb5276918f6a3f0b56aaf5c28f5898fc6/kmongo-serialization-mapping/src/main/kotlin/KMongoSerializationRepository.kt#L93

configuration = Configuration(
    encodeDefaults = true,
    classDiscriminator= "___type",
    nonEncodeNull = false
    )

HTH

theextremeprogrammer commented 2 years ago

@zigzago Thanks again for your reply and the additional info! I finally had a chance to prioritize this work and have worked through changes on my end. From what I can conclude, there doesn't appear to be any need to adjust the configuration defaults as the serialization is already ignoring unknown keys. 👍🏻

Also, I didn't realize that MongoDB uses bson encoding - I'm still somewhat new to Mongo, so thank you for taking the time to share that (very rudimentary, I am embarrassed I didn't already know) detail. 😅

haste8 commented 2 years ago

Anyone else that might stumble across this and doesn't want to serialize nulls. Do the following before creating the kmongo client:

ObjectMappingConfiguration.serializeNull = false