Kotlinx.Serialization part1

Peter Nagy
The Startup
Published in
4 min readJan 12, 2021

--

Kotlinx.Serialization library a very interesting library. I have written an article about one reason why I recommend to use it in a Kotlin project.

Most of the serialization libraries using reflection (like GSON, Jackson, etc…). I think reflection is a hack. With reflection we are able to do lot of things what normal way is not possible. Like we can set null value to a non-nullable field. And reflection is not the most fast way how can instantiate an object. But Kotlinx library will use generate code and it will call the objects constructor with this will help us to set default values and keep the contract (about the type of the fields).

Setup Kotlinx Serialization library

First of all let look at the release table which Kotlin version is recommended to use our Kotlinx library.

Now latest stabile version of the Kotlinx serialization lib: 1.0.1
We can use it with Kotlin 1.4.20 and 1.4.21, anyway we need 1.4.x version of the Kotlin compiler.

First we need to add a new plugin to the build.gradle file:

plugins {
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.10'
}
or old version:apply plugin: 'kotlinx-serialization'

and we need to add this line of code to the project related build.gradle:

buildscript {
ext.kotlin_version = '1.6.10'
repositories { mavenCentral() }

dependencies {
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}

and last but not least add this line to your project dependencies:

dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2"
}

(Wait a minute Kotlinx serialization not just json serializer. There are some extra libraries which support other protocols like: Protocol buffers, CBOR, Properties, HOCON)

In my article I will write about Json serialization, and I will write about android aspect. (Kotlinx library is multiplatform library you can use it with Kotlin multiplatform in your JS, iOS, Android, Web project).

If you use it in your Android project and you are using Retrofit, then there is a good news there is an official lib to use Kotlinx serialization with Retrofit (thanks for Jake Wharton !!!).

When we want to use it we need add "@Serializable" annotation to our class.

@Serializable
data class Data(val text: String, val age: Int)

And after it we can serialize or deserialize Data class

val jsonString = Json.encodeToString(data)orval object = Json.decodeFromString<Data>(jsonString)

This is really easy. :)
Every class has a serializer which can identify data type and serializes it. With @Serializeble annotation compiler will generate some code with a default implementation (automatic). That sounds good, however there are a lot of cases when it is not enough for us. For example when we serialize something like a Color we want to serialize it with hexa string like in CSS. (white -> "FFFFFF", and black -> "000000" it contains RGB color)

In this case we have to create our custom serializer:

object ColorAsStringSerializer : KSerializer<Color> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)

override fun serialize(encoder: Encoder, value: Color) {
val string = value.rgb.toString(16).padStart(6, '0')
encoder.encodeString(string)
}

override fun deserialize(decoder: Decoder): Color {
val string = decoder.decodeString()
return Color(string.toInt(16))
}
}

(you can find this example in Kotlinx serialization Github page)

There are lot of reason why we want to write a custom serilizer (like convert to other format or other type). Anyway there are lot cases how and why we want to write a custom serializer.

Now when you want to use this custom serializer you can use it when you serialize that object:

val colorWhite = Color.WHITEval jsonString = Json.encodeToString(ColorAsStringSerializer, colorData)=> "FFFFFF"

It is much more flexible when we are using it with @Serializable annotation:

@Serializable(with = ColorAsStringSerializer::class)
class Color(val rgb: Int)

Or we want to use it in another data class:

@Serializable
data class ViewData(val viewName: String, @Serializable(with = ColorAsStringSerializer::class) val backgroundColor: Color, @Serializable(with = ColorAsStringSerializer::class) val textColor: Color)

In this case we do not have to use custom serializer when encode or decode the object.

Ok, and what can we use if we want to use different name for serialization? Like json has an id like "background_color" and we want to map to our backgroundColor field.

Then there is @SerialName annotation.

@Serializable
data class FormData(val formName: String, @SerialName("background_color") backGroundColor)

So, it seems library gives us same things what other libraries gave (custom serializer, mapping different id with our object's field name). Easy to use it. This library is strong type serializer lib. 100% written in Kotlin. And it is not using reflection. These reasons why I recommend to use it.

Next part of this series:

If you found this post useful? Kindly tap the 👏 button below and follow, thanks :) .

--

--