Sitemap

Using gRPC for Communication between Microservices

5 min readMar 27, 2024

--

Press enter or click to view image in full size
Using gRPC for Communication between Microservices

Microservice communication is an important part of microservice architecture. One of the ways to make communication across microservices happen is using by gRPC. Today we are diving into the method of using gRPC for microservice communication. For the implementation, I will employ .NET 7. But before that we need to understand what is gRPC.

What is gRPC?

gRPC is a remote-call-procedure protocol that offers faster communication among services. In gRPC, two services hosted on different resources can communicate by directly calling each other's functions. The functions must be defined with identical definitions in the .proto files of each service. gRPC basically creates a server-client relation between microservices.

For more detailed introduction and concepts of gRPC, visit their site.

For this article, I will use Inventory-Product example. Let’s create two microservices, one is ProductService and other is InventoryService. Here ProductService will work as client and InventoryService will work as Server.

Note: This article expects its readers to have prior knowledge of microservice architecture or at least they know how to implement a simple microservice architecture in .NET.

The process of creating gRPC connection between microservices include following steps.

Steps:

1. Create identical .proto files in the services you want to connect.
2. Define gRPC service and gRPC messages in .proto file (also known as proto buffers or protobuf).
3. Register the protobuf service as server/client in the project file (.csproj) of microservice.
4. Implement the gRPC service in .cs file.

For communicating between services with gRPC we first need to create proto files in the communicating microservices.

What are .proto files?
Proto files are protocol buffers (protobuf) which are used as the Interface Definition Language (IDL) that are used to define the gRPC services.

In .proto files we have:
1. gRPC service definition
2. request/reply message definition. (This message can be assumed as DTO of the request and response of the gRPC call)

Get Haad Baig’s stories in your inbox

Join Medium for free to get updates from this writer.

Below are the examples of simple definition of gRPC message and service.

// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
// The greeting service definition.
service gRPCService {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}

Creating Proto files

Let’s create a proto file for our Product-Inventory example.

  • Create folder with name Proto in the root directory of the project
  • Create a file InventoryProduct.proto in the folder and copy following code in the file.
syntax = "proto3";

option csharp_namespace = "InventoryProductService";

package greet;

// The greeting service definition.
service InventoryProductGRPC {
// get items
rpc GetItems (HelloRequest) returns (ItemList);
}

// The request message containing the user's name.
message HelloRequest {
string name = 1;
}

// The response message containing the greetings.
message HelloReply {
string message = 1;
}

message Item {
string name = 1;
int64 units = 2;
int64 price = 3;
}
message ItemList {
repeated Item items = 1;
}
  • Now copy this folder in the root directory of ProductService so that we have identical proto files in both microservices.

Note: Both microservices must have identical proto files with identical gRPC service names, parameters and return types.

Registering microservices as Server/Client

Let’s register our protocol buffers (.proto files) in the project files (.csproj file) of the microservices. We will register InventoryProduct.proto in InventoryService as Server and in ProductService as Client.

  • Open InventoryService.csproj file by double clicking on the name of microservice project in VS and paste following code inside <Project></Project> tag.
<ItemGroup>
<Protobuf Include="Protos\InventoryProduct.proto" GrpcServices="Server">
<Link>Protos\InventoryProduct.proto</Link>
</Protobuf>
</ItemGroup>
  • Open ProductService.csproj file by double clicking on the name of microservice project in VS and paste following code in <Project></Project> container.
<ItemGroup>
<Protobuf Include="protos\InventoryProduct.proto" GrpcServices="Client">
<Link>Protos\InventoryProduct.proto</Link>
</Protobuf>
</ItemGroup>

Here we have registered InventoryService as Server and ProductService as Client.

Implementing gRPC service

Now its time to implement InventoryProductGRPC service which we defined in out proto file. Since our InventoryService works as Server in this example, we will be implementing the InventoryProductGRPC service in InventoryService.

  • Create a folder with name services in the root directory of our server microservice, in our case that service is InventoryService.
  • Create a file with name InventoryProduct.cs and copy following code.
using Grpc.Core;
using InventoryProductService;

namespace Inventory.GRPCServices
{
public class InventoryProduct : InventoryProductGRPC.InventoryProductGRPCBase
{
private readonly ILogger<InventoryProduct> _logger;
public InventoryProduct(ILogger<InventoryProduct> logger)
{
_logger = logger;
}
public override Task<ItemList> GetItems(HelloRequest request, ServerCallContext context)
{
List<Item> items = new List<Item>() {
new Item() {Name = "IPhone 15", Units = 10, Price = 999},
new Item() {Name = "IPhone 14 Pro", Units = 10, Price = 899},
new Item() {Name = "IPhone 14", Units = 10, Price = 799},
new Item() {Name = "Samsung Z Flip 5", Units = 4, Price = 599},
new Item() {Name = "Motorola Razr Flip 40 Ultra", Units = 5, Price = 599},
};
ItemList list = new ItemList();
list.Items.AddRange(items);
return Task.FromResult(list);
}
}
}

Now we have successfully created our gRPC server and gRPC client and also provide comprehensive implementation for the gRPC service.

Important: In the above code, it is to be noted that we are using GRPCServices namespace. Also another point is, we have inherited a base-class for our service. We get this base class only if we register out protocol buffer (.proto file) as server in the project file. The name format this base class is always going to be [grpc_service_name].[grpc_service_name]Base. If we register the service as client, we will get an object class with name [grpc_service_name]Client (e.g InventoryProductGRPCClient). This object class is used to connect with gRPC server.

Connect and Communicate with Server

Now only thing left is for client_service to connect and communicate with server_service.

  • Create a folder with name services in the root directory of our client microservice, in our case that service is ProductService.
  • Create a simple service class for the ProductService and paste following function.
public Task<ItemList> GetInventoryItem()
{
using var channel = GrpcChannel.ForAddress("https://localhost:7286");
var client = new InventoryProductGRPCClient(channel);
var reply = client.GetItems(
new HelloRequest { Name = "Haad" });

return Task.FromResult(reply);
}
  • Also add following dependency in this service file before namespace.
using static InventoryProductService.InventoryProductGRPC;

Above function will directly connect with the Inventory microservice and establish a communication channel with it. Then using that channel, it calls the function for GetItems() and pass HelloRequest object as parameter. The reply will be the list of items which are being fetched from the DB of inventory microservice.

Conclusion

In this article we have seen a simple way of creating gRPC communication between two microservices. We have started from creating .proto files, then registering those files as server and client in required microservices, then implementing the gRPC service class and functions and finally making connection from client microservice to server microservice and transferring data between them. Complete code sample is available on following link.

https://github.com/haadbaig/.net-microservice-tutorial/tree/microservice-grpc-communication

This github repo has extensive code and also uses ocelot for API Gateway. There are files for kafka communication as well but that is the topic for another article.

If you have any question feel free to comment below or reach out to me on my linked in.
LinkedIn: https://www.linkedin.com/in/haadbaig

--

--