The Realm Kotlin SDK supports Kotlin Serialization. You can serialize specific Realm data types using stable serializers, or user-defined classes with an experimental full-document serialization API.
Realm Data Type Serializers
El Realm Kotlin SDK proporciona serializadores para los siguientes tipos de datos para KSerializer:
Tipo de datos de Realm | KSerializer for Type |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Los serializadores se encuentran en io.realm.kotlin.serializers.
Para ver ejemplos de cómo Realm serializa los diferentes tipos de datos, consulte Ejemplos de salida de serialización.
Deserializing Realm data types generates unmanaged data instances.
Register a Serializer for a Property
You can register a serializer for a specific property. Use the @Serializable annotation to bind to a specific Realm data type serializer.
class Frog : RealmObject { var name: String = "" var favoritePonds: RealmList<String> = realmListOf() }
Registrar un serializador para todas las apariciones en un archivo
You can register a serializer for all occurrences of that type within a file by adding the declaration to the top of the file:
(RealmSetKSerializer::class) import io.realm.kotlin.ext.realmSetOf import io.realm.kotlin.serializers.RealmSetKSerializer import io.realm.kotlin.types.RealmSet import kotlinx.serialization.UseSerializers
Then, any objects that have properties of that type within the file can use the serializer without individually registering it:
// These objects have RealmSet properties that get serializers // from declaring `@file:UseSerializers(RealmSetKSerializer::class)`. // No need to individually declare them on every `RealmSet` property in the file. class Movie : RealmObject { var movieTitle: String = "" var actors: RealmSet<String> = realmSetOf() } class TVSeries : RealmObject { var seriesTitle: String = "" var episodeTitles: RealmSet<String> = realmSetOf() }
Automatically Bind Realm Types to Serializers
Para vincular automáticamente todos los tipos Realm con sus serializadores, puedes añadir un fragmento que contenga todos los serializadores en la parte superior de un archivo:
( MutableRealmIntKSerializer::class, RealmAnyKSerializer::class, RealmDictionaryKSerializer::class, RealmInstantKSerializer::class, RealmListKSerializer::class, RealmSetKSerializer::class, RealmUUIDKSerializer::class )
Ejemplos de salida de serialización
Estos ejemplos ilustran cómo los diferentes tipos de datos de Realm se serializan usando un codificador JSON:
Tipo de datos de Realm | Serialization Type and Example | |||||||
|---|---|---|---|---|---|---|---|---|
MutableRealmInt | Serializes using a regular integer value. MutableRealmInt.create(35) serializes to 35 | |||||||
RealmAny | Serializes using a map containing a union of all values and its type. RealmAny.create("hello world") serializes to {"type": "STRING", "string": "hello world"}RealmAny.create(20) serializes to {"type": "INT", "int": 20} | |||||||
RealmDictionary | Serializes using a generic list. realmDictionaryOf("hello" to "world") serializes to {"hello": "world"} | |||||||
RealmInstant | Serializes as a BsonDateTime.RealmInstant.now() serializes to {"$date": {"$numberLong": "<millis>"}} | |||||||
RealmList | Serializes using a generic list. realmListOf("hello", world) serializes to ["hello", "world"] | |||||||
RealmSet | Serializes using a generic list. realmSetOf("hello", world) serializes to ["hello", "world"] | |||||||
BsonObjectId or ObjectId | Serializes as a BsonObjectId.ObjectId.create() serializes to {"$oid": <ObjectId bytes as 24-character, big-endian hex string>} | |||||||
RealmUUID | Serializes as a BsonBinary.RealmUUID.random() serializes to { "$binary": {"base64": "<payload>", "subType": "<t>"}} | |||||||
RealmObject | Serializes using the polymorphic setup defined by the user. Do this via the SerializersModule: |
Codificación EJSON para Atlas
Nueva en la versión 1.9.0.
Realm Kotlin SDK APIs that communicate directly with MongoDB Atlas use EJSON encoding. The SDK offers two types of EJSON encoders:
Un codificador limitado pero estable
An experimental encoder that offers full document serialization
The APIs that use these encoders include:
Servicios de aplicación Llamadas a funciones
Credentials with custom function authentication
Perfil de usuario y datos de usuario personalizados
Add KSerialization to Your Project
La compatibilidad con la serialización EJSON del SDK de Kotlin de Realm depende de la biblioteca oficial de serialización de Kotlin. Debe agregar la serialización de Kotlin.a tu proyecto. Usa la misma versión que la del SDK de Kotlin de Realm. Consulta la Matriz de Compatibilidad de Versiones en el repositorio de GitHub de realm-kotlin para obtener información sobre las dependencias compatibles con cada versión.
The @Serializable annotation in the following examples comes from the Kotlin Serialization framework.
Stable Encoder
The stable encoder does not support user-defined classes. You can use these argument types with the stable encoder:
Primitives
BSON
MutableRealmIntRealmUUIDObjectIdRealmInstantRealmAnyArreglo
Colección
Map
To return a collection or map, you can use BsonArray or BsonDocument.
Llamar a una función
You can call a Function using the stable encoder with a valid argument type, and deserialize the result.
In this example, we call the getMailingAddress Function with two string arguments, and get the result as a BsonDocument:
// The `getMailingAddress` function takes a first name and last name and returns an address as a BsonDocument val address = user.functions.call<BsonDocument>("getMailingAddress", "Bob", "Smith") assertEquals(address["street"], BsonString("123 Any Street"))
Custom Function Credentials
You can create a Credential for use with custom function authentication using the stable encoder as either a map or a BsonDocument:
val credentials = Credentials.customFunction( mapOf( "userId" to 500, "password" to "securePassword" ) ) val bsonCredentials = Credentials.customFunction( BsonDocument( mapOf( "userId" to BsonInt32(500), "password" to BsonString("securePassword") ) ) ) app.login(credentials)
Perfil de usuario y datos personalizados
Puedes acceder a un perfil de usuario o datos de usuario personalizados utilizando el codificador estable como un(a) BsonDocument:
val user = app.currentUser!! val userProfile = user.profileAsBsonDocument() assertEquals(userProfile["email"], BsonString("my.email@example.com"))
val user = app.currentUser!! val customUserData = user.customDataAsBsonDocument() assertEquals(BsonString("blue"), customUserData?.get("favoriteColor"))
Full-Document Encoder
The full-document encoder enables you to serialize and deserialize user-defined classes. You can define and use custom KSerializers for your type with Atlas features that communicate directly with MongoDB Atlas using EJSON encoding. The full-document encoder supports contextual serializers.
Importante
Esto es experimental
La implementación actual de la serialización completa de documentos es experimental. Llamar a estas API cuando su proyecto utiliza una versión de Kotlin Serialization diferente a la de la dependencia de Realm puede causar un comportamiento indefinido. Consulte la matriz de compatibilidad de versiones en el repositorio de GitHub realm-kotlin para obtener información sobre las dependencias admitidas de cada versión.
Required Imports
To use this feature, add one or more of the following imports to your file as relevant:
import kotlinx.serialization.Serializable import io.realm.kotlin.annotations.ExperimentalRealmSerializerApi import org.mongodb.kbson.ExperimentalKBsonSerializerApi import kotlinx.serialization.modules.SerializersModule import io.realm.kotlin.serializers.RealmListKSerializer
Define a Serializer
When you use serialization in the Realm Kotlin SDK, you can define a serializer in one of two ways:
Add the
@Serializableannotation to a classDefine a custom KSerializer for your type, and pass it to the relevant API
class Person( val firstName: String, val lastName: String )
Puedes configurar un serializador EJSON personalizado para tu aplicación en el AppConfiguration, como en un caso donde desees utilizar un serializador contextual:
class Frogger( val name: String, val date: LocalDateTime ) AppConfiguration.Builder(FLEXIBLE_APP_ID) .ejson( EJson( serializersModule = SerializersModule { contextual(DateAsIntsSerializer) } ) ) .build()
Experimental Opt-In
Because the full-document serialization API is experimental, you must add the relevant @OptIn annotations for the APIs you use.
Llamar a una función
You can call a Function using the experimental API with arguments or return types that use custom serializers.
En este ejemplo, llamamos a la función getMailingAddressForPerson con un objeto Person serializado y obtenemos el resultado como un objeto Address deserializado:
class Address( val street: String, val city: String, val state: String, val country: String, val postalCode: String ) class Person( val firstName: String, val lastName: String )
// The `getMailingAddressForPerson` function takes a Person object and returns an Address object using the experimental serializer val address = user.functions.call<Address>("getMailingAddressForPerson"){ add(Person("Bob", "Smith")) } assertEquals(address.street, "123 Any Street")
Tip
Atlas Function calls for the stable serializer and the experimental API serializer share the same method name. When invoking a function with no parameters, you must provide an empty block in the instruction for the experimental API.
val color = user.functions.call<PersonalFavorites>("favouriteColor") {}
Custom Function Credentials
Puedes definir un serializador personalizado para la autenticación de función personalizada usando la API experimental:
class CustomUserCredential( val userId: Int, val password: String )
And use it when creating a custom function credential:
val credentials = Credentials.customFunction( CustomUserCredential( userId = 500, password = "securePassword" ) ) app.login(credentials)
Perfil de usuario y datos personalizados
Define a custom serializer for user profile or custom data:
class UserProfile( val email: String )
class UserCustomData( val favoriteColor: String )
Y utiliza el serializador personalizado cuando accedas al perfil del usuario o a datos de usuario personalizados:
val user = app.currentUser!! val userProfile = user.profile<UserProfile>() assertEquals(userProfile.email, "my.email@example.com")
val user = app.currentUser!! val customUserData = user.customData<UserCustomData>() assertEquals("blue", customUserData!!.favoriteColor)
Other Serialization Libraries
Serialization methods used by libraries that depend on reflection, such as GSON do not work with the SDK by default.
This is because the SDK compiler plugin injects a hidden field into object models, prefixed with io_realm_kotlin_. The SDK uses this hidden field to manage internal object state. Any library that relies on fields instead of getters and setters needs to ignore this hidden field.
To use the SDK with external libraries such as GSON, exclude the hidden fields from serialization using a prefix match:
var gson: Gson = GsonBuilder() .setExclusionStrategies(object: ExclusionStrategy { override fun shouldSkipField(f: FieldAttributes?): Boolean = f?.name?.startsWith("io_realm_kotlin_") ?: false override fun shouldSkipClass(clazz: Class<*>?): Boolean = false }) .create()