Introduction to gRPC and using with .NET Core

Emre Ceylan
5 min readAug 6, 2020

--

Source: grpc.io

Introduction

To understand what is grpc, we should firstly look for what the rpc is. RPC (Remote Procedure Call) is a protocol that one program can use to request a service from a program located in another computer on a network without having to understand the network’s details. It is used for client-server based applications. It is used to call other processes on the remote systems like a local system. The main differences from REST are;

  • REST is about resources but RPC is more about actions
  • RPC uses contracts to define actions and messages

gRPC is open source RPC system developed by Google at 2015. It uses new generation HTTP/2 protocol. It does not use a human readable text based communication like REST, instead it uses Protocol Buffers to serialize and deserialize messages. It automatically generates client and server bindings for most programming languages like C++, Python, C#, Go, Node.js, Java etc.

Especially for microservices architecture, it is important to have a standard way to define service interfaces and underlying message interchange formats. gRPC offers a clean and powerful way to specify service contracts using protocol buffers. Therefore, gRPC is probably the most viable solution for building communication between services.

Main differences between REST and gRPC are;

  • Protobuf vs JSON: REST messages typically contain JSON which does not guarentee type-safety. But Protobuf is predefined model that guarentees type safety and provides fast serialization/deserialization.
  • HTTP/2 vs HTTP 1.1: HTTP 2 provides compression of request headers, binary protocol and request multiplexing over a single TCP connection
  • Streaming vs. Request-Response: REST supports only the request-response model in HTTP 1.1 but gRPC uses streams to send information constantly.
Source: grpc.io

Implementation

Firstly we are creating our grpc server project, .net core has a template named grpc service for it. You can find it from visual studio templates list.

Or with visual studio code, you can create project from terminal as follows;

dotnet new grpc

It includes a simple service named Greeter declared in greet.proto file under proto folder.

This file defines the service definition, actions and models that will be used in request and responses.

csharp_namespace definition is for overriding default generated namespace for class that created while building project. If you do not define this, package name will be used as namespace. In this example generated namespace would be “Greet” if we did not define the csharp_namespace.

Then we define our rpc service and methods. In our greeter service we have SayHello method that takes HelloRequest type and returns HelloReply message type.

Lastly we define the message types that will be used for request and response. These message types will be the models in our backend service.

For auto generating service and classes, proto file should be included in csproj file with “server” attribute.

Now we can implement the business logic for our rpc service.

We create the GreeterService and inherit from abstract class Greeter.GreeterBase that is generated from proto file by Grpc.AspNetCore package. In this class, SayHello method overrides the abstract method and returns HelloReply model.

Now we can configure the project in the startup file to add required services for rpc service and map the GreeterService to endpoint of project.

Now our service is ready to run, you can run it with “dotnet run” command. It will start to listen https://localhost:5001 address by default. You can change the listening port and TLS behaviour on Program.cs as follows;

It is time to create a client to interact with our example server. We can create a console application for this example. We should add following libraries to use as a grpc client;

  • Grpc.Net.Client
  • Google.Protobuf
  • Grpc.Tools

For creating the client code and for calling our Greeter service methods, we should add greet.proto file to our client project and then add into csproj with client attribute.

When we build the project, process will create client classes instead of server abstract classes. Now we can call our Greeter service in client project as follows;

We are creating a grpc channel with our server’s address and creating a greet service client with this channel. Then we can call the service methods with this client.

Let’s now update our greeter service and add new rpc method to return stream which is a sequence of messages read by client.

In this example we are returning multiple responses to client in the same request. Client will send request and start to listen responses until there are no messages.

If we want to call another grpc server from our own grpc server, we have to include server’s proto file and add it as grpc client in startup with dependency injection. Imagine that we have another grpc server which is written with node.js and we want to call it from our net core grpc server. Firstly add proto file to project.

We added proto file with client attribute to csproj file. When we build our project, process add necessary classes for client. Then we can inject example client to our project via startup as follows. In this example server will be listening on 5002 port.

We can now reach the example service client from DI service pool and call service with this client.

In this article we have talked about grpc and how to use grpc as server and client in .net core. You can find all files on my github repo as follows. You may ask me if you have further questions.

--

--