Search code examples
androidjsonkotlinserializationkotlinx

Kotlinx serialization of JSON Array to data class


For my Android app I try to parse a network response using Kotlinx serialization. The network response is a WebSocket Payload from Kraken and looks like a JSON array, that has elements without keys. I want to create a data class for this response and assign the missing keys. The network response looks like this:

 [
  324,
  {
    "a": [
      "65534.00000",
      8,
      "8.45840938"
    ],
    "b": [
      "65533.90000",
      0,
      "0.00352122"
    ],
    "c": [
      "65533.90000",
      "0.00458332"
    ],
    "v": [
      "2282.41761567",
      "3048.01677262"
    ],
    "p": [
      "65297.21555",
      "64608.96127"
    ],
    "t": [
      27317,
      38224
    ],
    "l": [
      "63319.60000",
      "61810.00000"
    ],
    "h": [
      "66420.00000",
      "66420.00000"
    ],
    "o": [
      "63319.60000",
      "61962.00000"
    ]
  },
  "ticker",
  "XBT/USD"
]

Solution

  • Finally I ended up with decoding the payload as JsonArray and feeding my Data Class with its content manually.

    Here is my Data Class:

    @Serializable
    data class Ticker(
        var channelID : String,
        var channelName : String,
        var pair : String,
        var ticker : TickerData,
    )
    
    @Serializable
    data class TickerData(
        @SerialName("a")
        val ask: Ask,
    
        @SerialName("b")
        val bid: Bid,
    
        @SerialName("c")
        val close: Close,
    
        @SerialName("h")
        val volume: Volume,
    
        @SerialName("l")
        val volumeWeightedAveragePrice: VolumeWeightedAveragePrice,
    
        @SerialName("o")
        val numberOfTrades: NumberOfTrades,
    
        @SerialName("p")
        val lowPrice: LowPrice,
    
        @SerialName("t")
        val highPrice: HighPrice,
    
        @SerialName("v")
        val openPrice: OpenPrice,
    )
    
    @Serializable
    data class Ask(
          var price: String,
          var wholeLotVolume: Int,
          var lotVolume: String,
    )
    
    @Serializable
    data class Bid(
        var price: String,
        var wholeLotVolume: Int,
        var lotVolume: String,
    )
    
    @Serializable
    data class Close(
        var price: String,
        var lotVolume: String,
    )
    
    @Serializable
    data class Volume(
        var today: String,
        var last24Hours: String,
    ) 
     
    @Serializable
    data class VolumeWeightedAveragePrice(
        var today: String,
        var last24Hours: String,
    )
    
    @Serializable
    data class NumberOfTrades(
        var today: String,
        var last24Hours: String,
    )
    
    @Serializable
    data class LowPrice(
        var today: String,
        var last24Hours: String,
    )
    
    @Serializable
    data class HighPrice(
        var today: String,
        var last24Hours: String,
    )
    
    @Serializable
    data class OpenPrice(
        var today: String,
        var last24Hours: String,
    )
    

    And this is my Payload Parser:

    class KrakenApiWebSocketPayload(val json: Json) {
        fun getTicker(response:String): Ticker {
            val tickerArray : JsonArray = json.decodeFromString(response)
            val tickerObject : JsonObject = tickerArray[1].jsonObject
    
            val ask : JsonArray = tickerObject.get("a")!!.jsonArray
            val bid : JsonArray = tickerObject.get("b")!!.jsonArray
            val close : JsonArray = tickerObject.get("c")!!.jsonArray
            val volume : JsonArray = tickerObject.get("h")!!.jsonArray
            val volumeWeightedAveragePrice : JsonArray = tickerObject.get("l")!!.jsonArray
            val numberOfTrades : JsonArray = tickerObject.get("o")!!.jsonArray
            val lowPrice : JsonArray = tickerObject.get("p")!!.jsonArray
            val highPrice : JsonArray = tickerObject.get("t")!!.jsonArray
            val openPrice : JsonArray = tickerObject.get("v")!!.jsonArray
    
            return Ticker(tickerArray[0].toString(),tickerArray[2].toString(),tickerArray[3].toString(),
                        TickerData(
                            Ask(ask[0].toString(),ask[1].toString().toInt(),ask[2].toString()),
                            Bid(bid[0].toString(),bid[1].toString().toInt(),bid[2].toString()),
                            Close(close[0].toString(),close[1].toString()),
                            Volume(volume[0].toString(),volume[1].toString()),
                            VolumeWeightedAveragePrice(volumeWeightedAveragePrice[0].toString(),volumeWeightedAveragePrice[1].toString()),
                            NumberOfTrades(numberOfTrades[0].toString(),numberOfTrades[1].toString()),
                            LowPrice(lowPrice[0].toString(),lowPrice[1].toString()),
                            HighPrice(highPrice[0].toString(),highPrice[1].toString()),
                            OpenPrice(openPrice[0].toString(),openPrice[1].toString())
    
                        )
            )
        }   
    }