Hello API is returning data in the following format ```{ "album": { "artist": "Michael J...
i
Hello API is returning data in the following format
Copy code
{
  "album": {
    "artist": "Michael Jackson",
    "tags": {
      "tag": [
        {
          "url": "https://www.last.fm/tag/pop",
          "name": "pop"
        },
        {
          "url": "https://www.last.fm/tag/soul",
          "name": "soul"
        }
      ]
    }
  }
}
The
tags
attribute contains a single child
tag
, so some kind of container (
TrackContainer
) class is required to parse this JSON:
Copy code
@Serializable
internal data class AlbumApiModel(
    @SerialName("artist") val artist: String,
    @SerialName("tracks") val tracks: TrackContainer? = null,
)

@Serializable
internal data class TrackContainer(
    @SerialName("track") val track: List<AlbumTrackApiModel>,
)
Since creation of this class is a bit verbose I wonder if there is a way to parse nested attributes without a need to define
TrackContainer
class- something like
@SerialName("tracks.track")
Copy code
@Serializable
internal data class AlbumApiModel(
    @SerialName("artist") val artist: String,
    @SerialName("tracks.track") val tracks: List<Track>? = null,
)
o
You can use a
JsonTransformingSerializer
on that property to unwrap the array into an object, removing the need for the container.
Copy code
class SingletonArrayUnwrappingSerializer<T : Any>(tSerializer: KSerializer<T>) :
    JsonTransformingSerializer<T>(tSerializer) {

  override fun transformDeserialize(element: JsonElement): JsonElement {
    if (element !is JsonArray) return element
    require(element.size == 1) { "Array size must be exactly 1 to unwrap it." }
    return element.first()
  }

  override fun transformSerialize(element: JsonElement): JsonElement {
    return buildJsonArray { add(element) }
  }
}
Btw your text switches terminology half way from
Tag
to
Track
i
Thx, I was hoping there will be a simpler way then a custom serialiser