grpc-kotlin
grpc-kotlin copied to clipboard
Support Kotlin serialization
Would the grpc-kotlin project be open to considering Kotlin serialization as an alternative fully supported wire format, in addition to protobuf? Grpc, in general, has an affinity for protobuf serialization, yet I see substantial value in using Kotlin's own serialization approach in a Kotlin-based grpc project:
- Increasingly popular in Kotlin universe (my presumption)
- More idiomatic for Kotlin than protobuf, reduces Java-centric external dependencies
- Supports an increasingly broad number of cross-platform/cross-language serialization formats: https://github.com/Kotlin/kotlinx.serialization/blob/master/formats/README.md
- Reduces or eliminates marshaling boilerplate for transforming Kotlin domain objects to and from protobuf-specific representations
- Easier to use from Android clients, with rich typing system - protobuf-lite works ok only for basic use cases in my experience
- Potentially easier debugging of data on the wire, depending on chosen Kotlin serialization format (e.g. cleartext format like JSON)
- Eliminates APK size overhead for protobuf codegen and protobuf library dependencies
I've been contemplating replacing protobuf with Kotlin serialization in my own project for these reasons; ultimately it just seems much nicer & easier to use, and less error-prone. I assume this can be done via ClientCalls
and ServerCalls
in a similar fashion as outlined here for the grpc-java case: https://grpc.io/blog/grpc-with-json/
I'd prefer to wait for higher-level APIs if there were an anticipation of future Kotlin serialization support. I don't have any specific expectations at this point, primarily wanted to put the idea out there. In case there is little need for additional APIs, some additional documentation or blog post might outline the approach instead.
Just want to add that I consider this relevant regardless of future first-party protobuf Kotlin generation availability. Using a pure Kotlin serialization stack vs. protobuf-derived Kotlin are pretty different approaches.
Can you discuss what new API would be necessary for your use cases? ClientCalls.kt, the "implementation" of gRPC-Kotlin, is already public API that doesn't impose any type restrictions on the parameter types. ServerCalls is the same.
Let me rephrase. From the blog post you linked to, it seems to me like you can use gRPC-Kotlin with kotlinx.serialization, today, as easily as you could use GSON with gRPC-Java, by using io.grpc.kotlin.{Client,Server}Calls.
It could conceivably make sense to add e.g. Marshaller
factories based on kotlinx.serialization, which would make things a little easier. I would prefer to avoid adding a new dependency from the gRPC-Kotlin runtime to kotlinx.serialization for that, so it might need to be a separate artifact.
Thank you for your feedback, it clarifies where things are with respect to current implementation, goals, and plans; I did not want to wander off on my own in case there is something in the pipeline already. Also good to receive confirmation that this is generally considered a feasible use case within the intended design parameters of grpc-kotlin, via ClientCalls
& ServerCalls
.
I think a follow-up blog post to the one I quoted could additionally help remove some inhibitions about this approach for those who might consider it. The protoc-generated GrpcKt classes let me hit the ground running, while using kotlinx.serialization requires some experimentation to get to the same point. Marshaller
factories may be even more useful for this.
To further elaborate on what may be helpful to have: right now I am moving toward manually marshaling the protobuf-generated Java objects back and forth in a separate layer to get to the kinds of Kotlin data structures that I actually want to work with in my business logic. I envision grpc-kotlin infrastructure where switching back and forth between kotlinx.serialization and proto serialization (including this additional object beautification marshaling layer) would be essentially seamless. I imagine that I will want to retain the additional object marshaling layer even when using the brand-new Kotlin protobuf generation, as I have found it rewarding to work with idiomatic Kotlin; I'm guessing this is more or less a standard approach in the industry.
I see. I'm not sure we'd be able to make this a priority, but I think we'd be willing to receive pull requests.
FWIW, my organization has no plans to use kotlinx.serialization ourselves. Marshalling isn't uncommon, but is far from universal; we find many data objects are adequately and idiomatically expressed as protos with extension functions and properties.