- Another blog: gRPC Introduction and Implementation using .NET Core 6
- Implementation video: watch video
- More advance video watch video
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 itgRPCService
. - Here, you will see
Protos
andServices
.
- Add
builder.Services.AddGrpc()
inprogram.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 inprogram.cs
.
- Now, add the following code to the Client’s
program.cs
(Here,https://localhost:7019
is obtained fromlaunchSettings.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 thebin
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 itgRPCService
. - Here, you will see
Protos
andServices
. - Add
builder.Services.AddGrpc()
inprogram.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 inprogram.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 fromlaunchSettings.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 thebin
folder, which contains the generated client. However, we cannot find it in that location because it is hidden.