Is it possible to handle polymorphic JSON structur...
# serialization
n
Is it possible to handle polymorphic JSON structures (are JSON structures that change depending on what is sent as input) with KotlinX Serialization?
Using the Prometheus Querying API which doesn't use static JSON structures ( https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats ) ☹️ . Hoping there is a straightforward way around this via KotlinX Serialization.
Can end up with this type of error in some situations when running the program:
Copy code
Querying series by cell_mean_voltage selector (on <http://xx.xx.xx.xx>:xxxx)...
Uncaught Kotlin exception: kotlinx.serialization.json.JsonDecodingException: Invalid JSON at 73: Encountered an unknown key battery
        at kfun:kotlin.Exception.<init>(kotlin.String?;kotlin.Throwable?)kotlin.Exception (0x2e7213)
        at kfun:kotlin.RuntimeException.<init>(kotlin.String?;kotlin.Throwable?)kotlin.RuntimeException (0x2e6dd3)
        at kfun:kotlinx.serialization.SerializationException.<init>(kotlin.String;kotlin.Throwable?)kotlinx.serialization.SerializationException (0x570483)
        at kfun:kotlinx.serialization.SerializationException.<init>(kotlin.String;kotlin.Throwable?;kotlin.Int;kotlin.native.internal.DefaultConstructorMarker)kotlinx.serialization.SerializationException (0x5705f4)
        at kfun:kotlinx.serialization.json.JsonException.<init>(kotlin.String)kotlinx.serialization.json.JsonException (0x59ccac)
        at kfun:kotlinx.serialization.json.JsonDecodingException.<init>(<http://kotlin.Int;kotlin.String|kotlin.Int;kotlin.String>)kotlinx.serialization.json.JsonDecodingException (0x59cf5a)
        at kfun:kotlinx.serialization.json.internal.JsonReader.fail(kotlin.String;kotlin.Int)kotlin.Nothing (0x5a1f5e)
        at kfun:kotlinx.serialization.json.internal.JsonReader.fail$default(kotlin.String;kotlin.Int;kotlin.Int)kotlin.Nothing (0x5a20a6)
        at kfun:kotlinx.serialization.json.internal.StreamingJsonInput.decodeObjectIndex#internal (0x5a6d25)
        at kfun:kotlinx.serialization.json.internal.StreamingJsonInput.decodeElementIndex(kotlinx.serialization.SerialDescriptor)ValueType (0x5a5e55)
        at kfun:org.digieng.promMan.SeriesData.$serializer.deserialize(kotlinx.serialization.Decoder)org.digieng.promMan.SeriesData (0x5c3755)
        at kfun:kotlinx.serialization.json.internal.decodeSerializableValuePolymorphic$kotlinx-serialization-runtime@kotlinx.serialization.json.JsonInput.(kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x5a39aa)
        at kfun:kotlinx.serialization.json.internal.StreamingJsonInput.decodeSerializableValue(kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x5a46ae)
        at kfun:kotlinx.serialization.ElementValueDecoder.decodeSerializableElement(kotlinx.serialization.SerialDescriptor;kotlin.Int;kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x56f909)
        at kfun:kotlinx.serialization.internal.ListLikeSerializer.readElement(kotlinx.serialization.CompositeDecoder;kotlin.Int;#GENERIC;kotlin.Boolean) (0x57dbd5)
        at kfun:kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(kotlinx.serialization.CompositeDecoder;kotlin.Int;#GENERIC;kotlin.Boolean;kotlin.Int) (0x57eaf1)
        at kfun:kotlinx.serialization.internal.AbstractCollectionSerializer.patch(kotlinx.serialization.Decoder;#GENERIC)#GENERIC (0x57e411)
        at kfun:kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(kotlinx.serialization.Decoder)#GENERIC (0x57e6e8)
        at kfun:kotlinx.serialization.json.internal.decodeSerializableValuePolymorphic$kotlinx-serialization-runtime@kotlinx.serialization.json.JsonInput.(kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x5a39aa)
        at kfun:kotlinx.serialization.json.internal.StreamingJsonInput.decodeSerializableValue(kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x5a46ae)
        at kfun:kotlinx.serialization.ElementValueDecoder.decodeSerializableElement(kotlinx.serialization.SerialDescriptor;kotlin.Int;kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x56f909)
        at kfun:org.digieng.promMan.SeriesQueryResponse.$serializer.deserialize(kotlinx.serialization.Decoder)org.digieng.promMan.SeriesQueryResponse (0x5c56a3)
        at kfun:kotlinx.serialization.json.internal.decodeSerializableValuePolymorphic$kotlinx-serialization-runtime@kotlinx.serialization.json.JsonInput.(kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x5a39aa)
        at kfun:kotlinx.serialization.json.internal.StreamingJsonInput.decodeSerializableValue(kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x5a46ae)
        at kfun:kotlinx.serialization.decode@kotlinx.serialization.Decoder.(kotlinx.serialization.DeserializationStrategy<#GENERIC>)Generic (0x56cf77)
        at kfun:kotlinx.serialization.json.Json.parse(kotlinx.serialization.DeserializationStrategy<#GENERIC>;kotlin.String)Generic (0x591d7e)
        at kfun:io.ktor.client.features.json.serializer.KotlinxSerializer.read(io.ktor.client.call.TypeInfo;<http://io.ktor.utils.io|io.ktor.utils.io>.core.Input)kotlin.Any (0x5bdb65)
        at kfun:io.ktor.client.features.json.JsonFeature.Feature.$install$lambda-1COROUTINE$17.invokeSuspend#internal (0x56998c)
        at kfun:io.ktor.client.features.json.JsonFeature.Feature.$install$lambda-1COROUTINE$17.invoke#internal (0x56a29f)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.loop#internal (0x4d4b0d)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.proceed#internal (0x4d418e)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.proceedWith#internal (0x4d4367)
        at kfun:io.ktor.client.features.HttpCallValidator.Companion.$install$lambda-1COROUTINE$37.invokeSuspend#internal (0x53b6f2)
        at kfun:io.ktor.client.features.HttpCallValidator.Companion.$install$lambda-1COROUTINE$37.invoke#internal (0x53bc8f)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.loop#internal (0x4d4b0d)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.proceed#internal (0x4d418e)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.execute#internal (0x4d4591)
        at kfun:io.ktor.util.pipeline.Pipeline.execute(#GENERIC_kotlin.Any;#GENERIC_kotlin.Any)#GENERIC_kotlin.Any (0x4cf360)
        at kfun:io.ktor.client.call.HttpClientCall.$receiveCOROUTINE$27.invokeSuspend(kotlin.Result<kotlin.Any?>)kotlin.Any? (0x522d67)
        at kfun:io.ktor.client.call.HttpClientCall.receive(io.ktor.client.call.TypeInfo)kotlin.Any (0x5233d6)
        at kfun:org.digieng.promMan.$callSeriesQueryRoute$lambda-11COROUTINE$14.invokeSuspend#internal (0x5da4b6)
        at kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) (0x308258)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith#internal (0x4d51d8)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.loop#internal (0x4d4d42)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.object-1.resumeWith#internal (0x4d6a6c)
        at kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) (0x308539)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith#internal (0x4d51d8)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.loop#internal (0x4d4d42)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.object-1.resumeWith#internal (0x4d6a6c)
        at kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) (0x308539)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith#internal (0x4d51d8)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.loop#internal (0x4d4d42)
        at kfun:io.ktor.util.pipeline.SuspendFunctionGun.object-1.resumeWith#internal (0x4d6a6c)
        at kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) (0x308539)
        at kfun:kotlinx.coroutines.DispatchedTask.run() (0x3f1b1a)
        at kfun:kotlinx.coroutines.EventLoopImplBase.processNextEvent()ValueType (0x3cbe40)
        at kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal (0x3ff9fd)
        at kfun:kotlinx.coroutines.runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic (0x3feab0)
        at kfun:kotlinx.coroutines.runBlocking$default(kotlin.coroutines.CoroutineContext?;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>;kotlin.Int)Generic (0x3ff01b)
        at kfun:org.digieng.promMan.main(kotlin.Array<kotlin.String>) (0x5c6658)
        at Konan_start (0x5de1ab)
        at Init_and_run_start (0x5fff4b)
        at __libc_start_main (0x7f50ecf31b97)
        at  (0x2a7029)
        at  ((nil))
n
I would be very surprised if the polymorphism features in KotlinX Serialization are able to cover this use case: https://prometheus.io/docs/prometheus/latest/querying/api/#flags