The API I'm working with returns objects (and their containing objects) in a "flat" format and I'm having trouble getting this to work elegantly with Retrofit and RxJava.
Consider this JSON response for an /employees/{id}
endpoint:
{
"id": "123",
"id_to_name": {
"123" : "John Doe"
},
"id_to_age": {
"123" : 30
}
}
Using Retrofit and RxJava, how do I deserialize this to a Employee
object with fields for name
and age
?
Ideally I'd like RxJava's onNext
method to be called with an Employee
object. Is this possible? Could this perhaps be done with some type of custom deserializer subclass (I'm using Gson at the moment)?
I realize I could create an EmployeeResponse
object that maps directly to the JSON response, but having to map the EmployeeResponse
to the Employee
object every time I use this in an activity seems kind of unfortunate. It also gets much more complicated when the flat response also contains other objects that need to get deserialized and set as fields on the Employee
.
Is there a better way?
The complete solution to this will seem like a lot, but this will let you write Retrofit interfaces with
Employee
instead ofEmployeeResponse
. Here's the game plan:EmployeeResponse
andEmployee
objects, whereEmployeeResponse
just maps exactly to what you'd get from the API. Treat the response as a builder forEmployee
and write a static factory method that returns anEmployee
from anEmployeeResponse
, ie.Employee employee = Employee.newInstance(response);
TypeAdapterFactory
for Gson. When Gson sees you request aEmployee
object, we will have the TypeAdapter actually create anEmployeeResponse
, then return theEmployee
via the static factory method described above.Your TypeAdapterFactory will look something like this:
Register the factory when you make Gson:
And now you can safely define all your Retrofit interfaces with
Employee
instead ofEmployeeResponse
.