IgnoreUnknownKeys for one type only with Kotlinx and Ktor

Viewed 1436

I am using Kotlinx serialization in a Ktor-app, and looking for an equivalent of Jacksons @JsonIgnoreProperties(ignoreUnknown = true) annotation. I am aware of the

install(ContentNegotiation) {
     json(Json{ ignoreUnknownKeys = true })
 }

I have a number of classes annotated @Serializable. Is there a way to apply ignoreUnknownKeys to one type class/type only, like I could do with Jackson?

1 Answers

You can do the following trick:

  1. Keep default value of ignoreUnknownKeys property (false) of Json format instance, you're giving to Ktor.
  2. For specific classes you want to be handled in special way, create additional custom serializers, which will use another format instance under the hood.
  3. Wire these serializers to Json format instance, you're giving to Ktor.

For convenience, you may define the following extension function for KSerializer<T>:

fun <T> KSerializer<T>.withJsonFormat(json: Json) : KSerializer<T> = object : KSerializer<T> by this {
    override fun deserialize(decoder: Decoder): T {
        // Cast to JSON-specific interface
        val jsonInput = decoder as? JsonDecoder ?: error("Can be deserialized only by JSON")
        // Read the whole content as JSON
        val originalJson = jsonInput.decodeJsonElement().jsonObject
        return json.decodeFromJsonElement(this@withJsonFormat, originalJson)
    }
}

Usage:

install(ContentNegotiation) {
    json(Json {
        serializersModule = SerializersModule {
            contextual(MyDataClass.serializer().withJsonFormat(Json { ignoreUnknownKeys = true }))
        }
    })
}
Related