'Use Int as a parameter for Kotlin data class

got a bit of a problem with creating a data class. First post, and a bit of a noob - be gentle :)

I'm trying to create a Kotlin data class to handle some responses from an API we use; the response of which looks a bit like this:

"data": {
        "devices": {
            "600": [
                {
                    "device_id": "[deviceId]", ...

What I'm having trouble with is the "600" bit - I can't find a way to create the data class with this as a parameter. Each time I declare the var/val - it's throwing an error, but doesn't provide any helpful options in the IDE. All the rest are strings, so "devices" becomes "val devices: String" and so on. But in this case the val is an Int, and I don't know how to declare this in the data class.

I want to have the API response re-worked to something more easily defined, but that'll take time. Can anyone tell me how I can pass the Int as the parameter?

This is the data class:

data class SimRetrieveDevicesResponse(
    val data: Devices,
    val error: String? = null,
)

data class Devices(
   
    val 600: List<DeviceInfo>? = null
   )

data class DeviceInfo(
    val device_id: String,
    val device_type: String,
    val network_id: String,
    val send_period_sec: Int,
    val loss_in_thousand: Int,
    val tti_application_id: String,
    val cmt_tenant_id: String,
)

Sorry I've called anything the wrong name...



Solution 1:[1]

Backtick-ing the val has fixed the error, and helped tremendously.

Solution 2:[2]

As stated in the comments, the mapping is more than likely for a map, so having a property called "600", back-ticked or not, is incorrect. As soon as you have another value like "700", you'd have to change your code.

Here's a working solution, based on the assumption from your JSON snippet that devices is a map of a list of device information:

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import io.kotest.assertions.withClue
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import org.junit.jupiter.api.Test

data class SimRetrieveDevicesResponse(
    val data: Devices,
    val error: String? = null,
)

data class Devices(val devices: Map<String, List<DeviceInfo>>)
data class DeviceInfo(
    val device_id: String,
    val device_type: String,
    val network_id: String,
    val send_period_sec: Int,
    val loss_in_thousand: Int,
    val tti_application_id: String,
    val cmt_tenant_id: String,
)

class StackOverFlowTest {
    @Test
    fun test() {

        val data = """
       {
         "data": {
           "devices": {
             "600": [
               {
                 "device_id": "device_id",
                 "device_type": "device_type",
                 "network_id": "network_id",
                 "send_period_sec": 2,
                 "loss_in_thousand": 3,
                 "tti_application_id": "tti_application_id",
                 "cmt_tenant_id": "cmt_tenant_id"
                 
               }
             ]
           }
         }
       }
      """.trimIndent()

        val mapper = jacksonObjectMapper()

        val response = mapper.readValue(data, SimRetrieveDevicesResponse::class.java)

        val device = response.data.devices["600"]
        withClue("Device should be present") {
            device.shouldNotBe(null)
        }
        device!!.first().device_id shouldBe "device_id"
    }
}

The assertions here use kotest, which you can add via this in your build.gradle.kts

testImplementation("io.kotest:kotest-assertions-core:$kotestVersion")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tom F
Solution 2 PaulNUK