SalomonBrys / Kotson

Kotlin bindings for JSON manipulation via Gson
MIT License
709 stars 37 forks source link

Non-nullables in model are ignored #23

Closed NeverwinterMoon closed 7 years ago

NeverwinterMoon commented 7 years ago

Say, I have data class User(val clientId: Int, val firstName: String)

Both properties can never be null, that is how it should be. But if I get JSON { clientId: null, firstName: null }, my User will have nulls in it without throwing any errors and it will break everything. Now, you might think that I should have nullable properties if my data coming in JSON may can contain them... But the design of back-end is such that if the user is not found, all the data properties are nulls. I would rather try/catch the error, like so:

 fun parseUser(response: Response): User? =
      try {
        mapper.fromJson<User>(response.body().string())
      } catch (e: Exception) {
        null
      }

The idea is that I don't need the User object at all if BE returned all properties as nulls.

Is there an elegant way to handle this situation? Note that I have much more fields in User model than I presented, all but one of them is never null, unless user is not found.

SalomonBrys commented 7 years ago

Unfortunately not, and that is not something that is going to change in Kotson :(

Kotson is a wrapper around Google's Gson for Java. It is not itself responsible for (de)serialization, it simply adds an easier API for Kotlin onto Gson.

Gson itself only uses Java's reflexivity API (not Kotlin's), so it does not understand the concept of nullability :(

Now, here how I would handle this (outside of raging against a bad back-end API design, of course):

data class User(val firstName: String, val lastName: String)

fun main(args: Array<String>) {
    val user = Gson().fromJson<User>("{ firstName: null, lastName: null }")
    @Suppress("SENSELESS_COMPARISON") // It does make sense... unfortunately :p
    if (user.firstName == null)
        throw Exception("User not found")
    else
        println("OK")
}

Turns out that, in Kotlin, you can check for the nullability of a non-nullable variable, which does not make sense... most of the time!

NeverwinterMoon commented 7 years ago

@SalomonBrys Thanks, I was already thinking of something similar to the solution you suggested and just implemented it. Are there no good serializing/deserializing libraries written in Kotlin?

SalomonBrys commented 7 years ago

@NeverwinterMoon You can try Klaxon, I myself have always used... Kotson ;)