diff --git a/examples/src/test/kotlin/KotlinXSerializationTest.kt b/examples/src/test/kotlin/KotlinXSerializationTest.kt index 5839be6e..f943aa78 100644 --- a/examples/src/test/kotlin/KotlinXSerializationTest.kt +++ b/examples/src/test/kotlin/KotlinXSerializationTest.kt @@ -26,6 +26,7 @@ import org.bson.codecs.configuration.CodecRegistries import org.bson.codecs.kotlinx.BsonConfiguration import org.bson.codecs.kotlinx.BsonDecoder import org.bson.codecs.kotlinx.BsonEncoder +import org.bson.codecs.kotlinx.BsonNamingStrategy import org.bson.codecs.kotlinx.KotlinSerializerCodec import org.bson.codecs.kotlinx.ObjectIdSerializer import org.bson.types.ObjectId @@ -133,6 +134,34 @@ internal class KotlinXSerializationTest { collection.drop() } + @Test + fun snakeCaseNamingTest() = runBlocking { + @Serializable + data class PaintOrder( + val ManufacturerName: String, + val QuantityOfCans: Int, + ) + + val collection = database.getCollection("orders2") + + // :snippet-start: snake-case-naming + val myCustomCodec = KotlinSerializerCodec.create( + bsonConfiguration = BsonConfiguration(bsonNamingStrategy = BsonNamingStrategy.SNAKE_CASE) + ) + + val registry = CodecRegistries.fromRegistries( + CodecRegistries.fromCodecs(myCustomCodec), collection.codecRegistry + ) + // :snippet-end: + + val paint = PaintOrder("Acme", 10) + collection.withCodecRegistry(registry).insertOne(paint) + val result = collection.withDocumentClass().find().first().toJson() + assertTrue(result.contains("quantity_of_cans")) + assertFalse(result.contains("ManufacturerName")) + collection.drop() + } + // :snippet-start: kserializer object InstantAsBsonDateTime : KSerializer { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("InstantAsBsonDateTime", PrimitiveKind.LONG) diff --git a/source/examples/generated/KotlinXSerializationTest.snippet.snake-case-naming.kt b/source/examples/generated/KotlinXSerializationTest.snippet.snake-case-naming.kt new file mode 100644 index 00000000..2f374d2b --- /dev/null +++ b/source/examples/generated/KotlinXSerializationTest.snippet.snake-case-naming.kt @@ -0,0 +1,7 @@ +val myCustomCodec = KotlinSerializerCodec.create( + bsonConfiguration = BsonConfiguration(bsonNamingStrategy = BsonNamingStrategy.SNAKE_CASE) +) + +val registry = CodecRegistries.fromRegistries( + CodecRegistries.fromCodecs(myCustomCodec), collection.codecRegistry +) diff --git a/source/fundamentals/data-formats/serialization.txt b/source/fundamentals/data-formats/serialization.txt index 0a95e955..d6fe5f10 100644 --- a/source/fundamentals/data-formats/serialization.txt +++ b/source/fundamentals/data-formats/serialization.txt @@ -173,7 +173,8 @@ package to create a codec for your ``@Serializable`` data classes and customize what is stored. Use the ``BsonConfiguration`` class to define the configuration, -including whether to encode defaults, encode nulls, or define class discriminators. +including whether to encode defaults, encode nulls, define class discriminators, +or enforce snake case. To create a custom codec, install the ``bson-kotlinx`` dependency to your project. Select from the following tabs to see how to @@ -241,12 +242,33 @@ The following example shows how to create a codec using the .. literalinclude:: /examples/generated/KotlinXSerializationTest.snippet.custom-serialization.kt :language: kotlin +.. _kotlin-serialization-snake-case-eg: + +Implement Snake Case Naming Strategy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When using ``bson-kotlinx`` package v5.4 or later, you can direct the driver to +serialize data class field names written in camel case to snake case in MongoDB. +The following example shows how to create and register a custom codec +to convert data class field names into snake case by setting the +``bsonNamingStrategy`` parameter in a codec: + +.. code-block:: kotlin + :copyable: true + + import org.bson.codecs.kotlinx.BsonConfiguration + import org.bson.codecs.kotlinx.BsonNamingStrategy + +.. literalinclude:: /examples/generated/KotlinXSerializationTest.snippet.snake-case-naming.kt + :language: kotlin + For more information about the methods and classes mentioned in this section, see the following API documentation: - `KotlinSerializerCodec <{+api-root+}/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-kotlin-serializer-codec/index.html>`__ - `KotlinSerializerCodec.create() <{+api-root+}/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-kotlin-serializer-codec/-companion/create.html>`__ - `BsonConfiguration <{+api-root+}/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-bson-configuration/index.html>`__ +- `BsonNamingStrategy <{+api-root+}/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-bson-naming-strategy/index.html>`__ .. _kotlin-polymorphic: diff --git a/source/whats-new.txt b/source/whats-new.txt index 12874633..e3d7c6ef 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -31,6 +31,10 @@ What's New in 5.4 The 5.4 driver release includes the following changes, fixes, and features: +- Adds ``BsonConfiguration`` support for ``bson-kotlinx`` snake case conversion + during serialization. To learn more, see the + :ref:`kotlin-serialization-snake-case-eg` section on the Serialization page. + .. sharedinclude:: dbx/jvm/v5.4-wn-items.rst .. replacement:: install-bom-link