3

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

Beloo
  • 9,723
  • 7
  • 40
  • 71

1 Answers1

2

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

osipxd
  • 1,218
  • 16
  • 23
  • maybe this is the only way, but of course would be better to avoid additional annotation & additional reflection in jsonDeserializers, because kotlin already has out of the box feature for nullable & non-null fields. But i do not exclude that this is the only way – Beloo Nov 14 '17 at 10:46
  • @Beloo, Best way that I know - write something like this, but for Gson: https://github.com/square/moshi/blob/master/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt – osipxd Nov 14 '17 at 11:06
  • The old link is broken. Permalink here: https://github.com/square/moshi/blob/13a40edf5bb5779da81862d196df7ed4f944eea0/kotlin/reflect/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapter.kt – osipxd Aug 01 '19 at 09:06