RPC on .NET Core using gRPC

In this post on RPC on .Net Core using gRPC, we will see how .Net Core now has built-in support for gRPC. Also we will see a simple code example at the end of the post. You can read more about .Net here.

What is gRPC?

It is a high-performing Remote Procedure Call (RPC) framework and is language independant. It allows the client app to directly invoke methods on a server app as if it was an object which is local. Its makes it easier for developers to create distributed applications and services. gRPC is like other RPC (Remote Procedure Call) systems which are based around the idea of defining a service and then specifying the functions that can be called remotely with their types and parameters. To handle client calls, the server implements this interface and runs a gRPC server.

gRPC Protocol Buffers

Protocol buffers are Google’s open source implementation for serialization of structured data and gRPC uses protocol buffers. Note that it can work with JSON structures as well.

In protocol buffers, the initial step is to define the structure we need to serialize in an ordinary text file with a .proto extension which is called as a proto file. This data is structured as messages, where each message is a logical information containing a series of fields i.e. name-value pairs. Below is an example:

message Department {
    string name =1;
    int32 dept_id =2;
    bool has_hod=1;
}

The next step is to use the compiler protocol buffer called protoc to generate data access classes in the language from our proto definition. These in turn provide simple getter setters for each field (like name() and set_name())

Advantages of gRP:

  • Network usage is reduced by using binary serialization with Protobuf.
  • It is a lightweight and high-performing RPC framework.
  • It is language independent, by using contract first API style development and using proto buffers.
  • Supports wide variety of multi-language tools for creating strongly typed entities.

Because of the above advantages we can work with heterogeneous systems where more than one language is needed for development. We can also create micro-services which are lightweight.

.Net Core C# support for .proto files

Definitions for services and messages are in *.proto files since gRPC uses a contract-first API development style.

protobuf

syntax = "proto3";

service GreeterService {
    rpc GreetHelloWorld (HelloWorldRequest) returns (HelloWorldReply);
}

message HelloWorldRequest {
    string name = 1;
}

message HelloWorldReply {
    string message = 1;
}

Once *.proto files are included in a project, .NET types for services, clients and messages are automatically generated

Steps for above

  • Add a package reference to Grpc.Tools
  • Add *.proto files to the <Protobuf> item group as shown below
<ItemGroup>
<Protobuf Include="Protos\greet.proto" />
</ItemGroup>

ASP.NET Core hosted gRPC services

We can host gRPC services on ASP.NET Core. Once hosted, they can be integrated with ASP.NET Core features such as authentication/authorization, logging, etc.

The project template for the service will provide a starter service which can be used as shown in below code snipped:

public class HelloWorldService : GreeterService.GreeterServiceBase
{
    private readonly ILogger<HelloWorldService> _logger;

    public HelloWorldService(ILogger<HelloWorldService> logger)
    {
        _logger = logger;
    }

    public override Task<HelloWorldReply>GreetHelloWorld(HelloWorldRequest 
    request, ServerCallContext context)
    {
        _logger.LogInformation("Saying hello to {Name}", request.Name);
        return Task.FromResult(new HelloWorldReply
            {
                Message = "Hello " + request.Name
            });
    }
}

As you can see from the above code snippet, HelloWorldService inherits from the GreeterServiceBase, which in turn gets generated from the GreeterService service.  Remember that it was defined in the *.proto file. To enable client’s access to the service we define it in the Startup.cs as follows:

app.UseEndpoints(endpoints =>
{
    endpoints.MapGrpcService<HelloWorldService>();
});

.NET client to gRPC service call

As we discussed earlier that the clients in gRPC are strongly typed clients which are generated from *.proto files.

var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new GreeterService.GreeterServiceClient(channel);

var response = await client.GreetHelloWorld(new HelloWorldRequest { Name = "World" });

Console.WriteLine(response.Message);

Creating a gRPC client:

  • To create a gRPC client we have to use a channel.
  • The channel is nothing but a lasting connection to a gRPC service.
  • Using GrpcChannel.ForAddress the channel can then be created.

Disadvantages of gRPC client:

Since we discussed about the benefits of gRPC, we should also see the disadvantages as well. It has limited browser support since it uses HTTP/2 features heavily and currently no browser provides the level web requests hold required to support a gRPC client. Also it is not human readable since gRPC messages are encoded with Protobuf by default and its binary format is not human readable.

Azure Support

As of Nov 2019, gRPC is not supported on Azure App Service.

Summary

In this post on RPC on .Net Core using gRPC we saw that it is a powerful tool for ASP.NET Core developers. Though it is not a replacement for traditional HTTP APIs, it does offer improved productivity and performance benefits in some scenarios. Thanks for learning along with me. Keep visiting my blog.

Hitesh Boricha

I have a little over a decade experience in the IT industry. Having worked in various roles in this industry, I am passionate about technology.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.