Kotlinx Json vs Gson
By: Juraj Kušnier
Tags: Retrofit, Android, Gson, Kotlin, Json

If you have ever implemented any REST API in your mobile app, you should be familiar with JSON format.

JSON is an open-standard file format or data interchange format that uses human-readable text to transmit data objects consisting of attribute-value pairs and array data types.

The most common way how to parse JSON-format data to java/kotlin objects is by using one of the popular libraries like Jackson, Moshi or Gson. It’s likely that you are using kotlin, however, all previously mentioned libraries are java-based. Kotlin is 100% interoperable with java, however, because of some small nuances, sometimes you could encounter unexpected results.

Let’s define the User data class with some optional fields and default values. Don’t forget that data class and optional fields are kotlin features, not available in java.

And now you want to parse very simple JSON string.

{

"name" : "John Doe",

"email" : "john.doe@email.com"

}

Let’s add Gson dependencies to your project and create a unit test to see how this java library handles your input.

The test has passed! As you can see, gson library totally ignores your default values and uses 0 to complete missing primitive field and null instead of missing enum object. This means that gson deserialization even breaks kotlin null-safety and may cause app crash. To prevent this unwanted behavior, you could use nullable types and add supplementary code to handle these edge cases or you can use a smarter kotlin-based serialization library that can solve it for you.

Kotlin serialization comes to rescue us!

Kotlin serialization is kotlin oriented cross-platform reflectionless serialization library from JetBrains. This library doesn’t use reflectionless but rather explicit annotation @Serializable . After applying the annotation, the compiler plugin adds a special function serializer() on your companion object, returning serializer of type KSerializer . KSerializer object implements interfaces required for serializing and deserializing your data class. Library provides three ready to use formats: JSON, CBOR, and Protobuf. The advantage of this approach is that it works also outside of the JVM world, for example in Kotlin/Native or JavaScript.

Using Kotlin Serialization requires kotlin compiler v1.3.30 or higher. You have to add serialization plugin to your gradle build script, apply the plugin and add the dependency on the serialization runtime library. All information about the configuration are available in the documentation.

Now, you can Json class from kotlinx.serialization.json to serialize your input string.

All tests have passed! Json takes advantage of kotlin language features and returns a more predictable output.

You might have noticed that IDE complains about Json.parse() call. At the time of writing this article, the library is stable, however, there are no API compatibility guarantees between versions, that’s why some methods are called experimental and IDE shows you a warning when you try to use them.

Kotlinx.serialization + Retrofit

Retrofit is a very popular HTTP client for android and java from square. It doesn’t have build-in support for kotlin serialization but it allows you to add a converter factory for serialization and deserialization of objects. You could write your own converter factory or you can use one form Jake Wharton.

https://github.com/JakeWharton/retrofit2-kotlinx-serialization-converter

To start using Retrofit 2 Converter.Factory for Kotlin serialization just add library dependencies and add a converter factory when building your Retrofit instance using the asConvertFactory extension function.

val contentType = "application/json".toMediaType()



val retrofit = Retrofit.Builder()

.baseUrl("https://www.example.com")

.addConverterFactory(Json(JsonConfiguration(strictMode = false)).asConverterFactory(contentType))

.build()

You can also use JsonConfiguation to configure Json serializer, for example, to turn on/off encoding default values or to enable/disable strict mode. Strict mode is turned on by default, which prohibits unknown keys in the JSON and non-numerical values in floating-point numbers. It’s good practice to keep strict mode enabled in debug build and turn it off in release build of your app.

This article covers only very basic usage of kotlin serialization. If you want more information about how serializer works under the hood or how to write your own encoder/decoder, I would recommend you to read the documentation and watch the talk from KotlinConf 2019: Design of Kotlin Serialization by Leonid Startsev.