Moshi (Codegen) - Exclude a field or property and handle it manually without custom adapter

Viewed 463

How to exclude or skip a JSON field without using custom adapter in Moshi and Retrofit2? I wanted to handle this particular field since the API provider has a very terrible structure.

Example

{
   "status":{
      "message":"Success",
      "status":200
   },
   "data":[
      {
         "somefield":{
            "data":"foo"
         },
         "roi_by_year":{
            "2020_usd_percent":301.45619677746635,
            "2019_usd_percent":83.83497240467483,
            "2018_usd_percent":-72.35180629416075,
            "2017_usd_percent":1293.9968257264447,
            "2016_usd_percent":122.23036668622065,
            "2015_usd_percent":36.81278481514266,
            "2014_usd_percent":-57.34726933565019,
            "2013_usd_percent":5394.285470792129,
            "2012_usd_percent":156.47080487351116,
            "2011_usd_percent":1474.0066666666667
         }
      }
   ]
}

I will need to handle manually the roi_by_year since every year there could be a new property added and the key has decremental pattern, to be fair this should be restructured as an array which is the easiest but no they prefer anti-pattern approach.

I use plugin to generate a Moshi (Codegen) and using RxJava with Retrofit2.

This is how the Kotlin class would look like

@JsonClass(generateAdapter = true)
data class NewsItemModel(
    @Json(name = "samplefield")
    val sampleField: SampleField,
    @Json(name = "roi_by_year")
    val roiByYear: RoiByYear
)


@JsonClass(generateAdapter = true)
data class RoiByYear(
    @Json(name = "2020_usd_percent")
    val usdPercent: Double,
    @Json(name = "2019_usd_percent")
    val usdPercent: Double,
    @Json(name = "2018_usd_percent")
    val usdPercent: Double,
    @Json(name = "2017_usd_percent")
    val usdPercent: Double,
    @Json(name = "2016_usd_percent")
    val usdPercent: Double,
    @Json(name = "2015_usd_percent")
    val usdPercent: Double,
    @Json(name = "2014_usd_percent")
    val usdPercent: Double,
    @Json(name = "2013_usd_percent")
    val usdPercent: Double,
    @Json(name = "2012_usd_percent")
    val usdPercent: Double,
    @Json(name = "2011_usd_percent")
    val usdPercent: Double
)

My approach is to skip the RoiByYear and handle it myself by iterating through JSON names in order to be adaptable for upcoming new year without updating the code yearly. I was able to do this in Volley with Java like this

                                    JSONObject roi = object.getJSONObject("roi_by_year");
                                    JSONArray keys = roi.names();

                                    List<Double> year_roi = new ArrayList<>();

                                    if (keys != null)
                                        for (int j = 0; j < keys.length(); j++) {
                                            String key = keys.getString(j); // Here's the dynamic key
                                            double val = optionalDouble(roi, key); // Here's value
                                            year_roi.add(val);
                                        }

Here I am instead using List and add each value, I should now use Pair as well so I could now store the key and value all together.

Now I have problems:

  1. How to skip a field/property from Moshi Codegen but continue to serialize the other.
  2. How to retrieve the roi_by_year field from the Retrofit2 since the response data type class is based on NewsItemModel.
  3. How to thank you for saving me
0 Answers
Related