Search code examples
javagsonkotlinjson-deserialization

Null-safe network response using Gson and Kotlin


Assuming you have such data-class pojo, which represents typical gson-based representation of a response which comes from a server.

data class User(
        @field:SerializedName("id")
        val id: String,
        @field:SerializedName("name")
        val name: String,
        @field:SerializedName("user_phone")
        val phone: String?)

id and name fields are required, phone field is optional
So the appropriate json this model expects, for example:

{
   "id": "someHash",
   "name": "John Snow"
}

Sometimes server can send json like:

{
   "id": "someHash"      
}

Unfortunately such json is parsed successfully without any error, because gson uses unsafe reflection and was written for java. So as a result there will be corrupted kotlin model with null stored in non-null field

I want to provide validation for this model on the json-deserialization layer, because it is better to receive an error right there, not in any other part of application, which expects non-null field.
And i'm looking for any consize solution for this problem.

Of course you can provide some explicit validation function for each model like

fun User.validate() {
    if (id == null) throw JsonParseException("'id' is null!")
    if (name == null) throw JsonParseException("'name' is null!")
}

and call it by hand in any place but it produces a lot boilerplate code, which we always try to avoid. And also ide warns this as it thinks unnecessary null checking


Solution

  • You can use custom JsonDeserializer that will validate fields annotated by something like @RequiredField and automatically throw exception if it is null.

    How to do it you can find here: Gson optional and required fields