Search code examples
jsonserializationkotlinktorkotlin-multiplatform

Ktor: Serialize/Deserialize JSON with List as root in Multiplatform


How can we use kotlin.serialize with Ktor's HttpClient to deserialize/serialize JSON with lists as root? I am creating the HttpClient as follows:

HttpClient {
       install(JsonFeature) {
           serializer = KotlinxSerializer().apply {
               setMapper(MyClass::class, MyClass.serializer())
               setMapper(AnotherClass::class, AnotherClass.serializer())
           }
       }
       install(ExpectSuccess)
   }

Appears I need to setMapper for List, however that is not possible with generics. I see I can get the serializer for it with MyClass.serializer().list, but registering it to deserialize/serialize on http requests is not straight forward. Anyone know of a good solution?


Solution

  • Update with ktor 1.3.0:

    Now you're able to receive default collections(such a list) from the client directly:

    @Serializable
    data class User(val id: Int)
    
    val response: List<User> = client.get(...)
    // or client.get<List<User>>(...)
    

    Before ktor 1.3.0:

    There is no way to (de)serialize such JSON in the kotlinx.serialization yet.

    For serialization you could try something like this:

    fun serializer(data: Any) = if (data is List<*>) {
       if (data is EmptyList) String::class.serializer().list // any class with serializer 
       else data.first()::class.serializer().list
    } else data.serializer()
    

    And there are no known ways to get the list deserializer.