Skip to content

Commit ef426ee

Browse files
authored
DOCSP-42666: serialization (mongodb#39)
* DOCSP-42666: serialization * todo in whats new * fix * vale * MM PR fixes 1 * RL tech PR fixes 1
1 parent 0991759 commit ef426ee

File tree

8 files changed

+472
-8
lines changed

8 files changed

+472
-8
lines changed

snooty.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ api = "https://mongodb.github.io/mongo-java-driver/{+version-number+}/apidocs/mo
3333
java-api = "https://mongodb.github.io/mongo-java-driver/{+version-number+}"
3434
core-api = "{+java-api+}/apidocs/mongodb-driver-core"
3535
kotlin-docs = "https://kotlinlang.org"
36+
serialization-version = "1.5.1"

source/data-formats.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Specialized Data Formats
2121
:titlesonly:
2222
:maxdepth: 1
2323

24+
/data-formats/serialization
2425
/data-formats/bson
2526
/data-formats/time-series
2627

@@ -30,7 +31,13 @@ Specialized Data Formats
3031
Overview
3132
--------
3233

33-
You can use several types of specialized document data formats in your {+driver-short+}
34+
The {+driver-short+} supports the ``kotlinx.serialization`` library for
35+
serializing and deserializing {+language+} objects. You can use this
36+
library to convert between MongoDB documents and different data formats
37+
in your application. To learn more about serialization, see the
38+
:ref:`kotlin-sync-serialization` guide.
39+
40+
You can use several types of specialized document data formats in your
3441
application. To learn how to work with these data formats, see the following
3542
sections:
3643

source/data-formats/serialization.txt

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
.. _kotlin-sync-serialization:
2+
3+
====================
4+
Kotlin Serialization
5+
====================
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: code example, data model, conversion, polymorphism
13+
14+
.. contents:: On this page
15+
:local:
16+
:backlinks: none
17+
:depth: 2
18+
:class: singlecol
19+
20+
Overview
21+
--------
22+
23+
You can use the ``kotlinx.serialization`` library when
24+
serializing and deserializing {+language+} objects in your application.
25+
26+
The driver provides an efficient ``Bson`` serializer that you can use with
27+
classes marked with the ``@Serializable`` annotation to handle the
28+
serialization of {+language+} objects to BSON data.
29+
30+
Although you can use the {+language+} serialization ``Json``
31+
library, the ``Json`` serializer does *not* directly support BSON value types such
32+
as ``ObjectId``. You must provide a custom serializer that can handle the
33+
conversion between BSON and JSON.
34+
35+
We recommend installing the ``bson-kotlinx`` library to support
36+
custom codecs that have configurations to encode defaults, nulls, and
37+
define class discriminators.
38+
39+
.. TODO fix the link in the following note
40+
41+
.. note::
42+
43+
To learn how to use the ``Codec`` interface instead of the
44+
``kotlinx.serialization`` library to specify custom
45+
serialization behavior, see the Codecs guide.
46+
47+
You might choose to use {+language+} serialization if you
48+
are already familiar with the library or if you prefer
49+
to use an idiomatic approach.
50+
51+
Supported Types
52+
~~~~~~~~~~~~~~~
53+
54+
The {+driver-short+} supports the following types:
55+
56+
- All {+language+} types that are supported by the ``kotlinx.serialization`` library
57+
- All :manual:`BSON types </reference/bson-types>`
58+
59+
.. _kotlin-sync-add-serialization:
60+
61+
Add the Serialization Dependencies to Your Project
62+
--------------------------------------------------
63+
64+
You must install the official {+language+} serialization library,
65+
``kotlinx.serialization``, to serialize and deserialize data in your
66+
application. To learn more about this library, see the
67+
`kotlinx.serialization GitHub repository
68+
<https://github.com/Kotlin/kotlinx.serialization>`__.
69+
70+
Select from the following tabs to see how to add the serialization
71+
dependencies to your project by using either :guilabel:`Gradle` or
72+
:guilabel:`Maven`:
73+
74+
.. tabs::
75+
76+
.. tab::
77+
:tabid: Gradle
78+
79+
If you are using `Gradle <https://gradle.org/>`__ to manage your
80+
dependencies, add the following to your ``build.gradle.kts``
81+
dependencies list:
82+
83+
.. include:: /includes/data-formats/serialization-gradle-versioned.rst
84+
85+
.. tab::
86+
:tabid: Maven
87+
88+
If you are using `Maven <https://maven.apache.org/>`__ to manage your
89+
dependencies, add the following to your ``pom.xml`` dependencies
90+
list:
91+
92+
.. include:: /includes/data-formats/serialization-maven-versioned.rst
93+
94+
.. note:: bson-kotlin Dependency
95+
96+
You can also optionally install the ``bson-kotlin`` dependency
97+
through the default codec registry. This dependency uses reflection
98+
and the codec registry to support {+language+} data classes, but it does
99+
not support certain POJO annotations such as ``BsonDiscriminator``,
100+
``BsonExtraElements``, and ``BsonConstructor``. To learn more, see
101+
the `bson-kotlin API documentation <{+java-api+}/apidocs/bson-kotlin/index.html>`__.
102+
103+
Generally, we recommend that you install and use the faster
104+
``bson-kotlinx`` library for codec configuration.
105+
106+
.. _kotlin-sync-data-class-annotation:
107+
108+
Annotate Data Classes
109+
---------------------
110+
111+
To declare a class as serializable, annotate your {+language+} data
112+
classes with the ``@Serializable`` annotation.
113+
114+
You can use your data classes in your code as you use any other data
115+
class after you mark them as serializable. The {+driver-short+} and the
116+
{+language+} serialization framework handle BSON serialization and
117+
deserialization.
118+
119+
This example shows a sample data class with the following annotations:
120+
121+
- ``@Serializable``: Marks the class as serializable.
122+
- ``@SerialName``: Specifies the name of the ``id`` and ``manufacturer`` properties
123+
in the BSON document. This annotation can be used in place of the ``@BsonId`` and
124+
``@BsonProperty`` annotations, which are unsupported in serializable classes.
125+
- ``@Contextual``: Marks the BSON ``id`` property to use the built-in
126+
``ObjectIdSerializer``. This annotation is required for the driver to
127+
serialize BSON types correctly.
128+
129+
.. code-block:: kotlin
130+
131+
@Serializable
132+
data class PaintOrder(
133+
@SerialName("_id") // Use instead of @BsonId
134+
@Contextual val id: ObjectId?,
135+
val color: String,
136+
val qty: Int,
137+
@SerialName("brand")
138+
val manufacturer: String = "Grumbacher" // Use instead of @BsonProperty
139+
)
140+
141+
.. note:: POJO Annotations Limitation
142+
143+
You cannot use annotations from the
144+
``org.bson.codecs.pojo.annotations`` package on a data class marked
145+
with the ``@Serializable`` annotation.
146+
147+
To learn more about serializable classes and available annotations,
148+
see `Serializable classes
149+
<https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/basic-serialization.md#serializable-classes>`__
150+
in the ``kotlinx.serialization`` library documentation.
151+
152+
Custom Serializer Example
153+
~~~~~~~~~~~~~~~~~~~~~~~~~
154+
155+
You can create a custom serializer to handle how your data is
156+
represented in BSON. The {+driver-short+} uses the ``KSerializer``
157+
interface from the ``kotlinx.serialization`` library to implement custom
158+
serializers. You can specify the custom serializer as the parameter to
159+
the ``@Serializable`` annotation for a specific field.
160+
161+
The following example shows how to create a custom
162+
``KSerializer`` instance to convert a ``kotlinx.datetime.Instant`` to a
163+
``BsonDateTime``:
164+
165+
.. literalinclude:: /includes/data-formats/serialization.kt
166+
:language: kotlin
167+
:start-after: start-kserializer
168+
:end-before: end-kserializer
169+
:dedent:
170+
171+
The following code shows the ``PaintOrder`` data class in which the
172+
``orderDate`` field has an annotation that specifies the custom
173+
serializer class defined in the preceding code:
174+
175+
.. literalinclude:: /includes/data-formats/serialization.kt
176+
:language: kotlin
177+
:start-after: start-ks-dataclass
178+
:end-before: end-ks-dataclass
179+
:emphasize-lines: 5
180+
:dedent:
181+
182+
To learn more about the methods and classes mentioned in this section,
183+
see the following API documentation:
184+
185+
- `KSerializer
186+
<{+kotlin-docs+}/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-k-serializer/>`__
187+
in the {+language+} documentation
188+
189+
- `Instant
190+
<{+kotlin-docs+}/api/kotlinx-datetime/kotlinx-datetime/kotlinx.datetime/-instant/>`__ in the {+language+} documentation
191+
192+
- `BsonEncoder
193+
<{+java-api+}/apidocs/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-bson-encoder/index.html>`__
194+
195+
- `BsonDecoder
196+
<{+java-api+}/apidocs/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-bson-decoder/index.html>`__
197+
198+
.. _kotlin-sync-custom-codec:
199+
200+
Customize the Serializer Configuration
201+
--------------------------------------
202+
203+
You can use the ``KotlinSerializerCodec`` class from the ``org.bson.codecs.kotlinx``
204+
package to create a codec for your ``@Serializable`` data classes and
205+
customize what the driver stores in MongoDB.
206+
207+
Use the ``BsonConfiguration`` class to define the configuration,
208+
which can include whether to encode defaults, encode nulls, or define
209+
class discriminators.
210+
211+
To create a custom codec, your project must have the ``bson-kotlinx``
212+
dependency. See the :ref:`kotlin-sync-add-serialization` section of this
213+
guide for installation instructions.
214+
215+
You can define your codec by using the `KotlinSerializerCodec.create()
216+
<{+java-api+}/apidocs/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-kotlin-serializer-codec/-companion/index.html>`__
217+
method, then you can add the codec to the registry.
218+
219+
Custom Codec Example
220+
~~~~~~~~~~~~~~~~~~~~
221+
222+
The following example shows how to create a codec by using the
223+
``KotlinSerializerCodec.create()`` method and then configure it to *not*
224+
encode defaults:
225+
226+
.. literalinclude:: /includes/data-formats/serialization.kt
227+
:language: kotlin
228+
:start-after: start-codec
229+
:end-before: end-codec
230+
:dedent:
231+
232+
To learn more about the methods and classes mentioned in this section,
233+
see the following API documentation:
234+
235+
- `KotlinSerializerCodec
236+
<{+java-api+}/apidocs/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-kotlin-serializer-codec/index.html>`__
237+
238+
- `KotlinSerializerCodec.create()
239+
<{+java-api+}/apidocs/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-kotlin-serializer-codec/-companion/create.html>`__
240+
241+
- `BsonConfiguration
242+
<{+java-api+}/apidocs/bson-kotlinx/bson-kotlinx/org.bson.codecs.kotlinx/-bson-configuration/index.html>`__
243+
244+
.. _kotlin-sync-polymorphic:
245+
246+
Polymorphic Serialization
247+
-------------------------
248+
249+
The {+driver-short+} natively supports serialization and deserialization
250+
of polymorphic classes. When you mark a sealed interface and data
251+
classes that inherit that interface with the ``@Serializable``
252+
annotation, the driver uses a ``KSerializer`` implementation to handle
253+
conversion of your types to and from BSON.
254+
255+
When you insert an instance of a polymorphic data class into MongoDB,
256+
the driver adds the field ``_t``, the
257+
discriminator field. The value of this field is the data class name.
258+
259+
Polymorphic Data Classes Example
260+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261+
262+
The following example creates an interface and two data classes that
263+
inherit that interface. In the data classes, the ``id`` field is marked
264+
with the annotations described in the
265+
:ref:`kotlin-sync-data-class-annotation` section:
266+
267+
.. literalinclude:: /includes/data-formats/serialization.kt
268+
:language: kotlin
269+
:start-after: start-poly-classes
270+
:end-before: end-poly-classes
271+
:dedent:
272+
273+
Then, you can perform operations with data classes as usual. The
274+
following example parametrizes the collection with the ``Person``
275+
interface, then performs operations with the polymorphic classes
276+
``Teacher`` and ``Student``. When you retrieve documents, the driver
277+
automatically detects the type based on the discriminator value and
278+
deserializes them accordingly.
279+
280+
.. io-code-block::
281+
:copyable: true
282+
283+
.. input:: /includes/data-formats/serialization.kt
284+
:language: kotlin
285+
:start-after: start-poly-operations
286+
:end-before: end-poly-operations
287+
:dedent:
288+
289+
.. output::
290+
:language: console
291+
292+
Retrieving by using data classes
293+
Teacher(id=..., name=Vivian Lee, department=History)
294+
Student(id=..., name=Kate Parker, grade=10)
295+
296+
Retrieving by using Person interface
297+
Teacher(id=..., name=Vivian Lee, department=History)
298+
Student(id=..., name=Kate Parker, grade=10)
299+
300+
Retrieving as Document type
301+
Document{{_id=..., _t=Teacher, name=Vivian Lee, department=History}}
302+
Document{{_id=..., _t=Student, name=Kate Parker, grade=10}}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.. code-block:: kotlin
2+
:caption: build.gradle.kts
3+
4+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:{+serialization-version+}")
5+
implementation("org.mongodb:bson-kotlinx:{+full-version+}")
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.. code-block:: xml
2+
:caption: pom.xml
3+
4+
<dependency>
5+
<groupId>org.jetbrains.kotlinx</groupId>
6+
<artifactId>kotlinx-serialization-core</artifactId>
7+
<version>{+serialization-version+}</version>
8+
</dependency>
9+
<dependency>
10+
<groupId>org.mongodb</groupId>
11+
<artifactId>bson-kotlinx</artifactId>
12+
<version>{+full-version+}</version>
13+
</dependency>

0 commit comments

Comments
 (0)