I am using Retrofit and Parceler libraries in order to communicate with my server.
The server has the following two API methods:
GET /api/metadata/{id}
that returns the following JSON
{
"id": 1,
"active": true,
"location": {
"type": "Point",
"coordinates": [
30.0000,
30.0000
]
}
}
POST /api/metadata/{id} that expects the following JSON
{
"id": 1,
"active": true,
"location_latitude": 30.0000,
"location_longitude": 30.0000
}
That is so for historic reasons and cannot change.
In my android application, I declare Retrofit in the following way:
public interface ServerApi {
@GET("/api/metadata/{id}")
Metadata getMetadata(@Path("id") int id);
@POST("/api/metadata/{id}")
Metadata updateMetadata(@Path("id") int id, @Body Metadata metadata);
}
Parcel classes are defined in the following way:
Metadata:
@Parcel
public class Metadata {
@SerializedName("id")
private Integer id;
@SerializedName("location")
private GeometryPoint location;
@SerializedName("location_latitude")
private float locationLatitude;
@SerializedName("location_longitude")
private float locationLongitude;
public void setId(Integer id) {
this.id = id;
}
public void setLocationLatitude(float locationLatitude) {
this.locationLatitude = locationLatitude;
}
public void setLocationLongitude(float locationLongitude) {
this.locationLongitude = locationLongitude;
}
public void setLocation(GeometryPoint location) {
this.location = location;
}
public Integer getId() {
return id;
}
public float getLocationLatitude() {
return locationLatitude;
}
public float getLocationLongitude() {
return locationLongitude;
}
public GeometryPoint getLocation() {
return location;
}
}
GeometryPoint:
@Parcel
public class GeometryPoint {
@SerializedName("type")
private String type;
@SerializedName("coordinates")
private float[] coordinates;
public void setType(String type) {
this.type = type;
}
public void setCoordinates(float[] coordinates) {
this.coordinates = coordinates;
}
public String getType() {
return type;
}
public float[] getCoordinates() {
return coordinates;
}
}
I would like to use Metadata class throughout my application. I would like to query the server, receive Metadata, update it, and send it to the server. Obviously, the formats of metadata differ between the GET and POST. As such, I'd like to have GET coverted to POST format upon receiving it.
My question is whether it is possible to somehow declare annotations so that Retrofit and Parceler would be aware of location
parameter, deserialize it from JSON but write it to Metadata
class via setLocation()
method where I could break it down into `location_latitude' and 'location_longitude'.
This is some pseudocode of the desired Metadata class:
@Parcel
public class Metadata {
@SerializedName("id")
private Integer id;
// I'd like not having location variable defined at all
// but use some annotation magic :)) to tell GSON to deserialize
// JSON and call setLocation() when it tries to process location
// parameter of the server response
/*
@SerializedName("location")
private GeometryPoint location;
*/
@SerializedName("location_latitude")
private float locationLatitude;
@SerializedName("location_longitude")
private float locationLongitude;
public void setId(Integer id) {
this.id = id;
}
public void setLocationLatitude(float locationLatitude) {
this.locationLatitude = locationLatitude;
}
public void setLocationLongitude(float locationLongitude) {
this.locationLongitude = locationLongitude;
}
public void setLocation(GeometryPoint location) {
this.location_latitude = location.getCoordinates()[1];
this.location_longitude = location.getCoordinates()[0];
}
public Integer getId() {
return id;
}
public float getLocationLatitude() {
return locationLatitude;
}
public float getLocationLongitude() {
return locationLongitude;
}
// No need for getLocation method
}
Or am I just being silly (I literally picked up Retrofit, Parceler, and GSON awareness yesterday) and should create two metadata classes MetadataExternal
and MetadataInternal
to use for receiving and sending to the server?