Feri Nagy
11/14/2023, 11:53 AM{
"-1":{
"name":"Foo",
},
"182":{
"name":"Bar",
},
"recordsCount":2
}
It is basically Map<String, CustomType>
, but with added recordsCount: Int
with the size of the map. We don’t own the api, so we are stuck with the structure. Any idea how to deserialize the map from the response? I thought we could somehow ignore the recordsCount
property or write a custom serializer, but did not find a way to do either. Any idea how to go about this?andylamax
11/14/2023, 11:55 AMFeri Nagy
11/14/2023, 12:34 PMJsonTransformingSerializer
for this. If anyone is interested in the code:
@Serializable(with = FooResponseSerializer::class)
data class FooResponse(
val data: Map<String, String>,
)
object FooResponseSerializer : KSerializer<FooResponse> {
private val delegateSerializer = WrappingSerializer
override val descriptor: SerialDescriptor = SerialDescriptor("FooResponse", delegateSerializer.descriptor)
override fun deserialize(decoder: Decoder): FooResponse {
val map = decoder.decodeSerializableValue(delegateSerializer)
return FooResponse(map)
}
override fun serialize(encoder: Encoder, value: FooResponse) {
encoder.encodeSerializableValue(delegateSerializer, value.data)
}
}
object WrappingSerializer : JsonTransformingSerializer<Map<String, String>>(MapSerializer(String.serializer(), String.serializer())) {
override fun transformDeserialize(element: JsonElement): JsonElement {
require(element is JsonObject)
val filtered = JsonObject(content = element.filterNot { it.key == "recordsCount" })
return super.transformDeserialize(filtered)
}
override fun transformSerialize(element: JsonElement): JsonElement {
require(element is JsonObject)
val added = element + ("recordsCount" to JsonPrimitive(element.size))
return super.transformSerialize(JsonObject(added))
}
}