kotlinktorkotlinx

IgnoreUnknownKeys for one type only with Kotlinx and Ktor


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?


Solution

  • 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 }))
            }
        })
    }