I enjoy using Protobufs to generate data objects in different languages with minimal effort, and I want to use Ktor as a RESTful service framework. Consider Swagger as an alternative. This is what is required for protobuf serde with Ktor. I wasn't able to find this in the Ktor docs.
Converter
class ProtobufConverter : ContentConverter {
override suspend fun convertForReceive(context: PipelineContext<ApplicationReceiveRequest, ApplicationCall>): Any? {
val request = context.subject
val channel = request.value as? ByteReadChannel ?: return null
return channel.readRemaining().readBytes()
.let {
request.type.javaObjectType.getMethod("parseFrom", ByteArray::class.java).invoke(null, it)
}
}
override suspend fun convertForSend(
context: PipelineContext<Any, ApplicationCall>,
contentType: ContentType,
value: Any
): Any? {
if (value !is MessageLite) return null
return ByteArrayContent(value.toByteArray(), contentType)
}
}
Content Negotiation and Routing
fun Application.configueRouting(service: ServiceImplementation) {
install(ContentNegotiation) {
register(ContentType.Application.ProtoBuf, ProtobufConverter()) // application/protobuf
}
routing {
post("/my-api") {
val req = call.receive<MyReq>() // MyReq protobuf message
val res = service.myApi(req) // MyRes protobuf message
call.respond(res)
}
}
}
I enjoy using Protobufs to generate data objects in different languages with minimal effort, and I want to use Ktor as a RESTful service framework. Consider Swagger as an alternative. This is what is required for protobuf serde with Ktor. I wasn't able to find this in the Ktor docs.
Converter
Content Negotiation and Routing