Hi gRPC team,
I’m exploring gRPC in C++ for learning purposes, and I want to completely avoid .proto files and Protobuf, keeping all message definitions and serialization fully in C++. For simplicity, I chose JSON (using nlohmann::json) and wrote a simple SerializationTraits adapter:
template <>
class grpc::SerializationTraits<nlohmann::json> {
public:
static grpc::Status Serialize(const nlohmann::json& json,
grpc::ByteBuffer* buffer,
bool* own_buffer) {
std::string s = json.dump();
grpc::Slice slice(s.data(), s.size());
*buffer = grpc::ByteBuffer(&slice, 1);
*own_buffer = true;
return grpc::Status::OK;
}
static grpc::Status Deserialize(grpc::ByteBuffer* buffer,
nlohmann::json* json) {
std::vector<grpc::Slice> slices;
buffer->Dump(&slices);
std::string data;
for (auto& s : slices) {
data.append(reinterpret_cast<const char*>(s.begin()), s.size());
}
try {
*json = nlohmann::json::parse(data);
} catch (const std::exception& e) {
return grpc::Status(grpc::StatusCode::INTERNAL,
std::string("JSON parse error: ") + e.what());
}
return grpc::Status::OK;
}
};
The official gRPC blog shows how to plug in a custom marshaller in Java with JSON:
https://grpc.io/blog/grpc-with-json/
However, I cannot find an equivalent “Marshaller” interface in C++ gRPC. My questions:
How do I provide my own serializer/deserializer (JSON) for request/response messages in C++ gRPC? Is SerializationTraits enough?
Is there a C++ API for writing a gRPC service fully without .proto definitions?
Can I register a service and methods manually, bypassing protoc code generation?
If SerializationTraits is the only option, how exactly do I hook it up so gRPC uses JSON instead of Protobuf?
Here’s what I tried: deriving from grpc::Service and calling AddMethod, but I get stuck on the last argument: RpcMethodHandler. I don’t have generated stubs, so I’m unsure what to pass or how to register the service correctly. And i cant seem to find any docs that show this.
A small additional question: is it possible to completely remove Protobuf dependency? Even if I don’t intend to use it, CMake seems to still require it.
Any guidance, code snippets, or references would be greatly appreciated.
Thanks,
Ilya