Search code examples
protocol-buffersprotobuf-netprotogen

Using ProtoBuf-net with gRPC


I am trying to build a PoC at work that utilizes gRPC. The google document here takes us through a sample application. I was wondering if protobuf-net, and specifically protogen, had the capability to understand service definitions and classes necessary to perform gRPC calls? Or is this something being worked on? Would it work if I use google's protoc for client and server code generation(which involves the service definitions and RPC calls) and protobuf-net for my business objects.


Solution

  • protobuf-net.Grpc is now a thing... albeit in preview. When .NET Core 3 comes out, we should be able to make this available.

    It is inspired by the WCF approach, so your service interfaces are defined via:

    namespace Whatever {
        [ServiceContract]
        public interface IMyAmazingService {
            ValueTask<SearchResponse> SearchAsync(SearchRequest request);
            // ... etc
        }
    }
    

    Servers just implement the interface:

    public class MyServer : IMyAmazingService {
        // ...
    }
    

    (how you host them depends on whether you're using ASP.NET Core, or the native/unmanaged gRPC libraries; both work)

    and clients just request the interface:

    var client = http.CreateGrpcService<IMyAmazingService>();
    var result = await client.SearchAsync(query);
    

    In the above case, this would be inferred to be the Whatever.MyAmazingService / Search service in gRPC terms, i.e.

    package Whatever;
    // ...
    service MyAmazingService {
        rpc Search (SearchRequest) returns (SearchResponse) {}
    }
    

    but the service/method names can be configured more explicitly if you prefer. The above is a unary example; for unary operations, the result can be any of T, Task<T>, ValueTask<T> - or void / Task / ValueTask (which all map to .google.protobuf.Empty, as does a method without a suitable input parameter).

    The streaming/duplex operations are inferred automatically if you use IAsyncEnumerable<T> (for some T) for the input parameter (client-streaming), the return type (server-streaming), or both (duplex).