I'm trying to implement JSON parsing in my Android application written in Kotlin using com.squareup.moshi
(v1.10.0).
Within the JSON file there are some properties that are not interesting in my case. Let's say, I only need the position to be able to mark the place on a map and the JSON looks like this:
"location":{
"address":{
"country":"..."
},
"position":{
"lat":47.469866,
"lon":19.062435
}
}
If I'm right, the data class in Kotlin should look like this if I'd like to parse that JSON:
@Parcelize
data class Location(
val address: Address,
val position: Position
): Parcelable
@Parcelize
data class Address(
val country: String
): Parcelable
@Parcelize
data class Position(
val lat: Double,
val lon: Double
): Parcelable
In Moshi's documentation I could find the transient
keyword to skip values which in Kotlin works as an annotation (@Transient
). As the documentation says:
Transient fields are omitted when writing JSON. When reading JSON, the field is skipped even if the JSON contains a value for the field. Instead it will get a default value.
Does it mean that if I don't want to have the address object, I should use the following code?
@Parcelize
data class Location(
@Transient val address: Address? = null,
val position: Position
): Parcelable
Also, what about in general terms? What if I have huge list of properties within a JSON object but I know I only need the 'position' object? Do I still have to create null
values to parse the JSON file field-by-field?
I think you are looking for something similar to GSON's
@Expose
annotations, wherein all model fields are excluded from parsing except those annotated.This functionality is currently not available in Moshi, so your current implementation using the
@Transient
annotation seems to be the most optimal solution. (See Moshi issues conversation here.)Extra food for thought:
You may also wish to use
@IgnoredOnParcel
on your transient fields since you are implementing theparcelable
interface. (Have a look here for some implementation pointers.)Alternatively you could separate your data model into 2 models - one for use in your app and one which reflects the server (JSON) schema (just as you have done above). The main data model for your app (which could implement parcelable) would contain only the fields you use (for example, the position field). When you parse your data, you then convert that data to your primary data model using some simple adapter. (This is often good practice anyhow, since server-side schemas are inherent to change. This way, any changes in the JSON schema wouldn't end having any ripple effect throughout your code.)