https://kotlinlang.org logo
#getting-started
Title
# getting-started
s

Somesh

04/26/2021, 4:39 PM
Hello, I am getting a response something like this where
status
,
message
&
data
keys will remain the same across the different API responses & only the content inside the
data
JSON object will change, in this example, I have a JSON object with a
member
key in other response I can have
tournament
key.
Copy code
{
  "status": true,
  "message": "Success",
  "data": {
    "member": {
      "id": 21,
      "emailAddress": "<mailto:abc@xyz.com|abc@xyz.com>",
      "firstName": "ABC"
    }
  }
}
Currently, I am making use of generics and doing something like this
Copy code
data class SignInResponse(
    val `data`: Data<Member>
) : BaseResponse()
and
BaseResponse
class has common JSON keys that I am getting, Here I'm using generics in data class passing the JSON class that is changing.
Copy code
open class BaseResponse {
    val status: Boolean  = false
    val message: String  = UNDEFINED
}


@Keep
data class Data<T>(val actualData: T)
But this approach is incomplete because the above code will expect a JSON key
actualData
but here JSON key can be a
member
,
tournament
, or anything. How can I pass the class in
Data
class so that it can support the above JSON response?
r

Roukanken

04/26/2021, 4:49 PM
hmm, I'm thinking that your model should be more like
BaseResponse<T>
which will also have
val data: T
member and then you would be parsing
DataResponse<SignInData>
type, where
SignInData
would be whatever you want:
Copy code
data class SignInData(
    val member: Member
)
not entirely sure what kind of parsing framework are you using, but you should be able to convince most of em to do it... especially if you know what
T
is before looking at json, which seem only dependent on what API you are calling
To show a bit more how it would work:
Copy code
// Your framework
inline fun <reified T> parse(text: String): T = TODO()

// Model
data class BaseResponse<T> (
    val status: Boolean,
    val message: String,
    val data: T,
)

data class SignInData(
    val member: Member
)

data class TournamentData(
    val tournament: Tournament
)

// Parse
val signInResponse = parse<BaseResponse<SignInData>>("")
val tournamentResponse = parse<BaseResponse<TournamentData>>("")

// these will exists in the model
val tournament: Tournament = tournamentResponse.data.tournament
val member: Member = signInResponse.data.member
android dance 1
s

Somesh

04/27/2021, 5:17 AM
@Roukanken I am using Gson with Retrofit and Your approach worked. I can't thank you enough. I have one more question.. because I really want to do the things right way.. Do you think that I am following right approach. because In these screenshot they are suggesting to follow different approach.
r

Roukanken

04/27/2021, 6:33 AM
It depends on details imho. If you are just using api like this, and every API call response has expected structure (eg,
/api/signIn
will give you will get you
member
in data,
/api/tournament
will get you
tournament
in data and so on) then imho this is the correct way. I would question the API design though, and if you are controlling the other end, I would think of designing the API differently - eg smth like
Copy code
data class SignIn(
    val info: BasicResponseInfo,
    val member: Member,
)

data class BasicResponseInfo(
    val status: Boolean,
    val message: String,
)
would be more friendly, or by using sealed classes to have
Response.Error
class and
Response.Success
but these would need changes from the API side - if we are just fitting it to that API, then the one I showed ya is the best way imho. Also if the responses can differ in structure based on parameters (eg,
/api?getWhat=signIn
,
/api?getWhat=tournament
, or similar) then I would look into sealed classes, but unsure if you can fit that without API changes - usually you need a "discriminator" so your JSON would need to have
type
field or similar:
Copy code
"data": {
    "type": "Tournament",
    "tournament": ...
}
(PS: writing in Slack with code is so ugh, I hope it looks correct on your end, cause Slack is smacking me every 2 lines)
s

Somesh

04/27/2021, 7:48 AM
If you are just using api like this...
Yes, This is how my API works.
I would question the API design though...
I have passed this to our API developer
writing in Slack with code is so ugh
Yes, same thing happed with me when I was writing the question Thank you for all the help. 🙏🏽
5 Views