Search code examples
androidkotlingsonandroid-jetpack-composeokhttp

Give GSON a type to deserialize and if the json doesn't match, deserialize it with another (Android Kotlin)


I'm doing an app which has to get responses from multiple apis, they serve the same job but they are different. While on may output

{
  "token": "AAAAABBBBB",
  "expires": "unixtimestamp",
  "username": "aaa",
  "password": "bbb"
}

another could follow the OAuth standard

{
  "access_token": "AAAABBBBCCCC",
  "refresh_token": "BBBBCCCCDDDD",
  "expires_in": 3599
}

I already have the types as data classes and know what api is responding (so i can match the data classes) i was wondering if there was a better alternative than just a when expression.

Thank you.


Solution

  • Not really sure what you are asking here.

    If you have two different returns which signify credentials which should be treated differently downstream, but you still want to return either one of them, I'd suggest using a sealed class to model the data.

    sealed class Credentials {
       data class BasicAuth(...): Credentials()
       data class OAuth(...): Credentials()
    }
    
    suspend fun getCredentials(): Credentials {
       val json: String = doStuff() // suspending function
    
       return serializeOAuth(json) ?: serializeBasic(json) ?: // throw or null
       private fun serializeOAuth(json: String): OAuth? = 
         try { 
             Gson().fromJson(json, OAuthCredentials::class)
         } catch(...) { return null }
    
       private fun serializeBasic(json: String): BasicAuth? = 
         try { 
             Gson().fromJson(json, BasicAuth::class)
         } catch(...) { return null }
    }
    

    Perhaps you could elaborate more on what the problem is if this does not help you.