0

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"
]
Peter Renz
  • 23
  • 5
  • What kind of a response is this? I don't see any pattern here. Can you explain a bit more on this? Also what kind of data class do you want? Can you give some outline for that? – Arpit Shukla Nov 08 '21 at 17:01
  • It is the Payload of the WebSocket from Kraken: [Kraken](https://docs.kraken.com/websockets/#message-ticker) I have a callback function, that pushes the updated data. What I try is to structure the Payload before. – Peter Renz Nov 09 '21 at 07:35

2 Answers2

0

For JSON array

[{
  "id": 324,
  "items": {
    "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"
    ]
  },
  "unit" : "ticker",
  "code" : "XBT/USD"}
]

Kotlin data class would be

import com.google.gson.annotations.SerializedName

   
data class Example (

   @SerializedName("id") var id : Int,
   @SerializedName("items") var items : Items,
   @SerializedName("unit") var unit : String,
   @SerializedName("code") var code : String

)

However your response does not look like a JSON array which should be of form:

[{},{},{}]

Your response is a normal array of form:

[,,,]
m'hd semps
  • 564
  • 4
  • 14
  • Thank you for the answer! I think it is a JSON Array, that contains values of type Int and String besides Objects. If there was a key to the value like in your example, one could assign a name insde the data class. But in my response the key is missing. – Peter Renz Nov 09 '21 at 07:25
0

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())

                    )
        )
    }   
} 
Peter Renz
  • 23
  • 5