https://kotlinlang.org logo
v

Vladimir Vasic

01/20/2021, 12:53 PM
Hello, I'm having a problem with polymorphic serialization with discriminator in request. When I try to serialize object my discriminator is not being added. I'm using ktor 1.5 and kotlinx serialization I'm gonna write mock classes to mimic my classes here:
Copy code
@Polymorphic
@Serializable
abstract class Base {

    @SerialName("property_1")
    abstract val property1: String

    @SerialName("property_2")
    abstract val property2: String
}

private const val DISCRIMINATORA = "5"

@Serializable
@SerialName(DISCRIMINATORA)
data class A(

@SerialName("property_1")
    override val property1: String,

@SerialName("property_2")
    override val property2: String,

@SerialName("propertyA")
    val propertyA: String,

) : Base()

private const val DISCRIMINATORB = "4"

@Serializable
@SerialName(DISCRIMINATORB)
data class B(

@SerialName("property_1")
    override val property1: String,

@SerialName("property_2")
    override val property2: String,

@SerialName("propertyB")
    val propertyB: String,

) : Base()
My koin definition is
Copy code
single {
    APIClient(baseUrl, get())
}

val polymorphicBaseRequestModule = SerializersModule {
    polymorphic(Any::class) {
        subclass(A::class)
        subclass(B::class)
    }
    polymorphic(Base::class) {
        subclass(A::class)
        subclass(B::class)
    }
}

single {
    HttpClient(OkHttp) {
        install(JsonFeature) {
            serializer = KotlinxSerializer(kotlinx.serialization.json.Json {
                isLenient = true
                ignoreUnknownKeys = true
                classDiscriminator = "hello"
                serializersModule =  polymorphicBaseRequestModule
            })
        }
}
My Request class is
Copy code
abstract class APIRequest<ReturnType : Any>(
    open val httpMethod: APIHTTPMethod = APIHTTPMethod.Get,
    open val contentType: String? = null,
    open val resourcePath: String = "/",
    open val urlParameters: HashMap<String, Any?>? = null,
    @Polymorphic
    open val httpBody: Any? = null
)
My API client is
Copy code
suspend inline fun <reified ReturnType : Any> send(apiRequest: APIRequest<ReturnType>): Result<ReturnType> {
    val builder = HttpRequestBuilder()
    builder.url.protocol = URLProtocol.HTTP

    builder.url.host = baseUrl
    builder.url.encodedPath = apiRequest.resourcePath

    builder.method = HttpMethod.parse(apiRequest.httpMethod.value)

    // Add headers
    apiRequest.contentType?.let {
        builder.headers.append("Content-Type", it)
    }

    // Add request body
    apiRequest.httpBody?.let { httpBody ->
        builder.body = httpBody
    }

    Sentry.addBreadcrumb("Resource path: " + apiRequest.resourcePath)

    return withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
        try {
            Result.success(client.request<ReturnType>(builder))
        }catch(e) {
            Log.d("error", e.response.content)
        }
}
What am I doing wrong?
j

Javier

01/20/2021, 1:46 PM
#serialization
v

Vladimir Vasic

01/20/2021, 4:01 PM
Thanks 🙂
7 Views