Kotlinx.serialization part5

Peter Nagy
3 min readApr 17, 2021

This series is about Kotlinx serialization library.

In the Part1 I wrote about the basic usage of the Kotlinx.serialization.

In the Part2 I wrote about how can we configure the Kotlinx.serilaization.

In the Part3 I wrote about Custom serializers and data classes.

In the Part4 I wrote an exact example how can we use custom serializer with 3rd party classes.

Now I would like to write about how can we handle an optional field.

Optional field means that field could be null (like not too important data). It seems not a problem because Kotlin has ? operator to handle nullable fields.

Example:

We have an User object, it has two fields: id and name. Id is a mandatory field but name is optional.

@Serializable
data class User(val id: Int, val name: String?)
val serializer = Json { }
val json = "{\"id\":123, \"name\":null}"
val user = serializer.decodeFromString<User>(json)

It is working!

Yes because in the JSON string there was a null value. Unfortunately a real life server response could be not so simple. It might be: server will send back a null value or it will not send any value (field will be missing from the response).

Let's see what will happen when a JSON do not contains a field.

val serializer = Json {  }
val json = "{\"id\":123}"
val user = serializer.decodeFromString<User>(json)

When we run this code we will get an Exception: kotlinx.serialization.MissingFieldException: Field ‘name’ is required, but it was missing

Ok, how possible ? We can think: our data class has an optional field and because of optional field it will be able to handle null value. Yes, it will be able to handle when we want to set a null value. But when serializer want to create a data class it is not the same: Kotlinx serializer will not able to determine if a field is missing what does it mean (1. it is an error, 2. field is null)

Let think about it: when we got a JSON string it will contains map (or dictionary) of fields. An JsonElement could be a key — value pair. Json serilaizer will create a Map <String, Object> or something else. And later from it will instantiate a real object. Kotlinx serilaizer will call the class's constructor but when a field is missing it will be not able to call that parameter (constructor need X argument however we have X-1 how). From that will cause the exception -> field is missing.

How can we solve this problem ? It is easy, because kotlinx serializer can handle default value when we have any field which could be missing from the response than we can set a default value in the class definition.

@Serializable
data class User(val id: Int, val name: String? = null)

This was an old fashion solution when name is missing it will be null. It means later we need to handle null check(s). It could cause some problem later. It is much better if we can set some default value. At the case of User we can set a non-null default value (empty string).

@Serializable
data class User(val id: Int, val name: String = "")

It is better because we do not have to take care when field is null. :)

So the best practice is use default value when we know if a non-mandatory field could be missing from the response. If a mandatory field is missing then Exception is a must!

Thanks for reading my article! If you found this post useful? Kindly tap the 👏 button below and follow :) .

--

--