Modern distributed applications require fast, lightweight, and efficient communication between services. One of the most powerful technologies for achieving this is gRPC.
gRPC stands for Google Remote Procedure Call. It is a high-performance framework developed by Google that enables communication between client and server applications using strongly typed contracts.
Why Use gRPC?
gRPC provides several advantages over traditional REST APIs, especially in microservices and enterprise applications.
- High performance communication using HTTP/2
- Strongly typed contracts
- Efficient binary serialization
- Cross-platform support
- Automatic client code generation
- Reduced payload size
Creating the gRPC Service
In a gRPC application, services and message contracts are defined inside
a .proto file.
greet.proto File
syntax = "proto3";
option csharp_namespace = "GrpcDemoService";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHelloToSomeOne(HelloRequest) returns (HelloReply);
}
// 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 .proto file acts as a contract between the client
and the server. Based on this file, .NET automatically generates
strongly typed classes for communication.
Implementing the gRPC Service
using Grpc.Core;
using GrpcDemoService;
namespace GrpcDemoService.Services
{
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHelloToSomeOne(
HelloRequest request,
ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
}
Configuring the gRPC Service
using GrpcDemoService.Services;
namespace GrpcDemoService
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddGrpc();
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.");
app.Run();
}
}
}
Creating the gRPC Client
Next, create a Console Application that consumes the gRPC service.
Step 1: Create Protos Folder
Create a folder named Protos inside the client project
and copy the greet.proto file from the service project.
Step 2: Install Required NuGet Packages
- Grpc.Net.Client
- Grpc.Tools
Step 3: Configure Proto File
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
When the project is built, .NET automatically generates
client classes inside the obj folder.
Implementing the gRPC Client
using Grpc.Net.Client;
using GrpcGreeterClient;
namespace GrpcDemoClient
{
internal class Program
{
static async Task Main(string[] args)
{
// The port number must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:7199");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloToSomeOneAsync(
new HelloRequest { Name = "Omer Javed" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
Running the Application
- Run the GrpcDemoService project
- Run the GrpcDemoClient project
Greeting: Hello Omer Javed
How gRPC Communication Works
- The client sends a request to the server
- Protocol Buffers serialize the request
- The server processes the request
- The response is returned to the client
Advantages of gRPC
- Better performance compared to REST APIs
- Strongly typed communication
- Automatic code generation
- Smaller payload sizes
- Efficient service-to-service communication
Conclusion
gRPC is an excellent choice for modern distributed systems, microservices architectures, and enterprise applications.
Using Protocol Buffers and HTTP/2, developers can create scalable, efficient, and strongly typed communication systems with minimal effort in ASP.NET Core.