Home > Back-end >  Ktor Serializer for class 'Response' is not found
Ktor Serializer for class 'Response' is not found

Time:12-04

Plugin and dependeny:

id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
implementation "io.ktor:ktor-serialization:$ktor_version"

Application file:

fun main() {
    embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
        install(ContentNegotiation) {
            json()
        }

        userRouter()
    }.start(wait = true)
}

UserRouter:

fun Application.userRouter() {
    routing {
        get("/users/{id}") {
            val id = call.parameters["id"]?.toInt() ?: -1
            val user = User("Sam", "[email protected]", "abc123")

            val response = if (id == 1) {
                Response("hahaha", false)
            } else {
                Response(user, true)        //< - here, use String type will work
            }

            call.respond(response)
        }
    }
}

User:

@Serializable
data class User(
    val name: String,
    val email: String,
    val password: String
)

Response:

@Serializable
data class Response<T>(
    val data: T,
    val success: Boolean
)

Logs:

2021-12-02 18:04:34.214 [eventLoopGroupProxy-4-1] ERROR ktor.application - Unhandled: GET - /users/7
kotlinx.serialization.SerializationException: Serializer for class 'Response' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
    at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
    at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:155)

Any help would be appreciated.

CodePudding user response:

The problem is that type for the response variable is Response<out Any> (the lowest common denominator between String and User types is Any) and the serialization framework cannot serialize the Any type.

CodePudding user response:

That's werid, the following works, but to me they are just the same:

get("/users/{id}") {
    val id = call.parameters["id"]?.toInt() ?: -1
    val user = User("Sam", "[email protected]", "abc123")

   /* val response = if (id == 1) {      //<- determine response here won't work, why?
        Response("hahaha", false)
    } else {
        Response(user, true)
    }

    call.respond(response)*/

    if (id == 1) {
        call.respond(Response("hahaha", false))
    } else {
        call.respond(Response(user, true))
    }
}
  • Related