Q: Why should we use gRPC?

Answer: The full form of gRPC is gRPC Remote Procedure Call (Google Remote Procedure Call). gRPC is a high-performance, open-source RPC (Remote Procedure Call) framework developed by Google. It is widely used for microservices communication because it offers fast, reliable, and efficient data transfer using HTTP/2, which supports features like multiplexing and bidirectional streaming. gRPC also provides strong typing, automatic code generation, and the use of Protocol Buffers, which is a highly efficient serialization format. Protocol Buffers (Protobuf) for serialization, and it supports multiple programming languages for both clients and servers, making it suitable for high-performance, cross-platform communication.

HTTP/1.x sends requests and responses sequentially over multiple connections, causing latency, while HTTP/2 multiplexes multiple requests and responses over a single connection, improving efficiency and reducing latency.


Q: Why use gRPC instead of RabbitMQ? Both work for data transfer.

Answer: gRPC and RabbitMQ are both used for communication, but they serve different purposes and are suited for different use cases:

  • gRPC is designed for synchronous communication between client and server. It is ideal for when you need direct, real-time, request/response interaction between services, especially for microservices or APIs.
  • RabbitMQ, on the other hand, is an asynchronous message broker, which is great for decoupling services and implementing message queues, event-driven architectures, or distributed systems that require message delivery and retries.

In summary, you would choose gRPC when you need low-latency, real-time communication between services, whereas RabbitMQ is more suited for handling asynchronous workflows, background tasks, or decoupling microservices.


Implementation 1 (Easy):

Service part

  • First, create a project called ASP.NET Core gRPC Service and name it gRPCService.
  • Here, you will see Protos and Services.

  • Add builder.Services.AddGrpc() in program.cs:
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
 
        // Add services to the container.
        builder.Services.AddGrpc(options=>
        {
            options.EnableDetailedErrors = true;
            options.IgnoreUnknownServices = true;
        });
 
        var app = builder.Build();
 
        // Configure the HTTP request pipeline.
        app.MapGrpcService<GreeterService>();
        app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
 
        app.Run();
    }
}
  • Now, create a proto file named greet.proto:
syntax = "proto3";
 
option csharp_namespace = "gRPCService";
 
package greet;
 
// Service definition
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}
 
// Request message
message HelloRequest {
  string name = 1;
}
 
// Response message
message HelloReply {
  string message = 1;
}
  • Now, create GreeterService.cs:
public class GreeterService : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }
 
    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}
  • Here, you can view in the project properties that GrpcServices="Server".

Client Part:

  • Now, create a console app named gRPCClient.
  • Install four NuGet packages: Google.Protobuf, Grpc.Net.Client, Grpc.Net.ClientFactory, Grpc.Tools.
  • Copy greet.proto from the Service project and paste it into the Client project.

  • After pasting the proto file into the client project, make sure to check that GrpcServices="Client" is set. Also, fix the include path. Otherwise, GreeterClient(channel) will not work in program.cs.

  • Now, add the following code to the Client’s program.cs (Here, https://localhost:7019 is obtained from launchSettings.json):
using Grpc.Net.Client;
using GrpcService;
using GrpcService.Protos;
var message = new HelloRequest
{
    Name = "SHOWYEAB AHMED"
};
var channel = GrpcChannel.ForAddress("https://localhost:7019");
var client = new Greeter.GreeterClient(channel);
var serverReply = await client.SayHelloAsync(message);
Console.WriteLine(serverReply.Message);
Console.ReadLine();
  • A file named GreeterGrpc.cs will be automatically generated in the bin folder, which contains the generated client. However, we cannot find it in that location because it is hidden.

Implementation 2:

Service part

  • First, create a project called ASP.NET Core gRPC Service and name it gRPCService.
  • Here, you will see Protos and Services.
  • Add builder.Services.AddGrpc() in program.cs:
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
 
        // Add services to the container.
        builder.Services.AddGrpc(options=>
        {
            options.EnableDetailedErrors = true;
            options.IgnoreUnknownServices = true;
        });
 
        var app = builder.Build();
 
        // Configure the HTTP request pipeline.
        app.MapGrpcService<GreeterService>();
        app.MapGrpcService<ProductService>();
        app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
 
        app.Run();
    }
}
  • Now, create a proto file named product.proto:
syntax = "proto3";
 
option csharp_namespace = "gRPCService";
 
package product;
 
service Product {
	rpc GetProductsInformation (GetProductDetail) returns (ProductModel);
}
 
message GetProductDetail{
	int32 productId = 1;
}
 
message ProductModel{
	string productName = 1;
	string productDescription = 2;
	int32 productPrice = 3;
	int32 productStock = 4;
}
  • Now, create ProductService.cs:
public class ProductService : Product.ProductBase
{
    private readonly ILogger<ProductService> _logger;
    public ProductService(ILogger<ProductService> logger)
    {
        _logger = logger;
    }
 
    public override Task<ProductModel> GetProductsInformation(GetProductDetail request, ServerCallContext context)
    {
        ProductModel productDetail = new ProductModel();
        if (request.ProductId == 1)
        {
            productDetail.ProductName = "Samsung TV";
            productDetail.ProductDescription = "Smart TV";
            productDetail.ProductPrice = 35000;
            productDetail.ProductStock = 10;
        }
        else if (request.ProductId == 2)
        {
            productDetail.ProductName = "HP Laptop";
            productDetail.ProductDescription = "HP Pavilion";
            productDetail.ProductPrice = 55000;
            productDetail.ProductStock = 20;
        }
        else if (request.ProductId == 3)
        {
            productDetail.ProductName = "IPhone";
            productDetail.ProductDescription = "IPhone 12";
            productDetail.ProductPrice = 65000;
            productDetail.ProductStock = 30;
        }
 
        return Task.FromResult(productDetail);
    }
}
  • Here, you can view in the project properties that GrpcServices="Server".
<ItemGroup> 
  <Protobuf Include="Protos\product.proto" GrpcServices="Server" />
</ItemGroup>

Client Part:

  • Now, create a console app named gRPCClient.
  • Install four NuGet packages: Google.Protobuf, Grpc.Net.Client, Grpc.Net.ClientFactory, Grpc.Tools.
  • Copy product.proto from the Service project and paste it into the Client project.
  • After pasting the proto file into the client project, make sure to check that GrpcServices="Client" is set. Also, fix the include path. Otherwise, ProductClient(channel) will not work in program.cs.
  • Remove this

<ItemGroup>
	<Protobuf Include="..\gRPCService\Protos\product.proto" GrpcServices="Client" />
  • Now, add the following code to the Client’s program.cs (Here, https://localhost:7019 is obtained from launchSettings.json):
using Grpc.Net.Client;
using GrpcService;
 
namespace gRPCClient
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            var channel = GrpcChannel.ForAddress("https://localhost:7019");
            var client = new Product.ProductClient(channel);
            var product = new GetProductDetail
            {
                ProductId = 3
            };
            var serverReply = await client.GetProductsInformationAsync(product);
            Console.WriteLine($"{serverReply.ProductName} | {serverReply.ProductDescription} | {serverReply.ProductPrice} | {serverReply.ProductStock}");  // IPhone | IPhone 12 | 65000 | 30
            Console.ReadLine();
        }
    }
}
  • A file named ProductGrpc.cs will be automatically generated in the bin folder, which contains the generated client. However, we cannot find it in that location because it is hidden.