The future of kotlinx.serialization integration

Hello there,

First of all, let me tell you that I enjoy using the Kotlin SDK and it’s great that there’s a dedicated SDK and not just Java. What I am having issues with is serialization and especially KotlinSerializationJsonSerializer. I’ve noticed that the current implementation limitations are due to this issue in kotlin.serialization. As you can see it’s already been resolved for some time. So I was wondering are there any plans to fix it now that’s there’s no obstruction anymore?

It is important to provide a fix, since it’s quite complicated to work with SQL++ API as a mandatory serialization is applied for all QueryParameters. The query() provides the serializer parameter, but there’s no transcoding. Gladly, for KV it’s not so bad due to Content.json, but often it’s not reasonable to use KV-only.

Thank you!

1 Like

Hi Gleb,

Thanks for the kind words about the Kotlin SDK. It’s a labor of love, and it’s great to hear people are using it.

Couchbase Kotlin SDK 1.5 will require Kotlin 1.9 or later, so we will finally be able to take advantage of the improved performance and stability of the kotlinx.serialization API. The release date for Couchbase Kotlin SDK 1.5 is to be determined, but I would be surprised if it’s more than a few months away.

Thank you for reporting the issues with KotlinxSerializationJsonSerializer and query parameters, which we’re now tracking as KCBC-179. We might need to design a new API for specifying query parameters in a way that preserves the type information required by kotlinx.serialization.

In the meantime, a potential workaround us to use JacksonJsonSerializer for serializing the query parameters, and KotlinxSerializationJsonSerializer for deserializing the result rows:

val kotlinxSerializer = KotlinxSerializationJsonSerializer()

val jacksonSerializer = JacksonJsonSerializer(
    JsonMapper.builder()
        .addModule(KotlinModule.Builder().build())
        .build()
)

@Serializable
data class MyThing(val name: String)

val cluster = Cluster.connect("couchbase://127.0.0.1", "Administrator", "password") {
    jsonSerializer = kotlinxSerializer
}
try {
    runBlocking {
        val queryResult = cluster.query(
            "select RAW ?",
            parameters = QueryParameters.positional(listOf(mapOf("name" to "foo"))),
            serializer = jacksonSerializer,
        ).execute()

        queryResult.rows.forEach {
            println(it.contentAs<MyThing>(serializer = kotlinxSerializer))
        }
    }
} finally {
    runBlocking { cluster.disconnect() }
}

Specifying serializers like this for every query is inconvenient, but hopefully it will tide you over until we deliver a real solution.

Thanks,
David

1 Like

We should be able to address KCBC-179 without having to wait for the Kotlin version upgrade.

Here’s a proposed syntax for query parameters that preserves type information required by kotlinx.serialization:

parameters = QueryParameters.named {
    param("type", "airline")
    param("limit", 3)
}

and for positional parameters:

parameters = QueryParameters.positional {
    param("airline")
    param(3)
}

Here’s the associated code review, in case you want to dig into the details: Code review for KCBC-179

@gleb.ignatev We’d love to hear your thoughts on this proposal.

Thanks,
David

2 Likes

Hi David,

Thanks for the quick response and the suggested workaround. The API for KCBC-179 looks great, can’t wait for it to be merged! Do I understand correctly that since the complete type info will be preserved, I can write my own JsonSerializer for kotlinx.serialization that would be able to handle nullable types?

1 Like

Hi Gleb,

Do I understand correctly that since the complete type info will be preserved, I can write my own JsonSerializer for kotlinx.serialization that would be able to handle nullable types?

The fix for KCBC-179 won’t resolve the nullability issue; it will just capture enough information to work with the existing kotlinx.serialization integration. In other words, it won’t be perfect right away, but at least it won’t explode anymore.

I do not believe full support for nullable types is possible without modifying the SDK source code. The TypeRef class will need to create a KSerializer<T> or capture enough information to create one later.

However, if you try this and are successful, I’d definitely like to hear about it!

Thanks,
David

1 Like

That’s what I thought, but just wanted to make it clear.

Anyway, thank you for your help and the workaround, I’ll play around it a bit more, but most likely I’ll be waiting for 1.5 then.

(post deleted by author)

Hi @gleb.ignatev ,

The upcoming patch release of the Couchbase Kotlin SDK fixes KCBC-180, which prevented KotlinSerializationJsonSerializer from serializing and deserializing nulls at the document root.

The fix (as well as the new query param API) is available in the latest snapshot. If you want to try it, configure your build tool to access Couchbase snapshots, and specify SDK version 1.4.8-SNAPSHOT.

If all goes to plan, the final 1.4.8 release should be available around the second week of February.

Thanks for encouraging us to address these issues, and please keep the feedback flowing.

Cheers,
David

1 Like