Modern distributed systems demand high performance, low latency, and strongly typed contracts. While REST APIs are still widely used, gRPC has become a preferred choice for internal microservice communication.
What is gRPC?
gRPC is a high-performance Remote Procedure Call (RPC) framework developed by Google. It uses:
- HTTP/2 for transport
- Protocol Buffers (Protobuf) for serialization
- Strongly typed service contracts
Instead of exchanging JSON over HTTP like REST, gRPC communicates using binary messages, making it faster and more efficient.
Why Use gRPC Instead of REST?
| Feature | REST | gRPC |
|---|---|---|
| Protocol | HTTP/1.1 | HTTP/2 |
| Data Format | JSON (text) | Protobuf (binary) |
| Performance | Medium | High |
| Streaming | Limited | Built-in (client/server/bidirectional) |
| Contract | Optional (Swagger) | Mandatory (.proto) |
| Language Support | Good | Excellent |
Use gRPC when:
- You are building microservices
- You need low latency
- You want strong contracts
- Services communicate internally
gRPC Architecture Overview
A gRPC system consists of:
- .proto file – Service contract definition
- Server – Implements the service
- Client – Calls the service methods
- Generated code – Created from
.protousing tooling
Step 1: Create a gRPC Service in .NET
Create the Project
dotnet new grpc -n GrpcDemo
cd GrpcDemo
This template creates:
- gRPC service
- Sample
.protofile - HTTP/2 configuration
Step 2: Understand the .proto File
File: Protos/greet.proto
syntax = "proto3";
option csharp_namespace = "GrpcDemo";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Key Elements
- service → Defines gRPC service
- rpc → Method definition
- message → Request/response models
- proto3 → Latest Protobuf syntax
Step 3: Implement the gRPC Service
File: Services/GreeterService.cs
using Grpc.Core;
namespace GrpcDemo.Services;
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(
HelloRequest request,
ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = $"Hello {request.Name}!"
});
}
}
Step 4: Configure the gRPC Server
File: Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<GreeterService>();
app.MapGet("/", () =>
"gRPC service is running.");
app.Run();
Step 5: Enable HTTP/2
gRPC requires HTTP/2.
- Development (Kestrel)
- Already enabled by default.
- Production (IIS / Nginx)
- Ensure HTTP/2 is enabled in hosting configuration.
Step 6: Create a gRPC Client
Create a Console App:
dotnet new console -n GrpcClient
Add Required Packages
dotnet add package Grpc.Net.Client
Client Code
using Grpc.Net.Client;
using GrpcDemo;
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "Anna" });
Console.WriteLine(reply.Message);
Step 7: gRPC Streaming in .NET
One of gRPC’s strongest features is streaming.
Server Streaming Example
rpc GetMessages (HelloRequest) returns (stream HelloReply);
Server Implementation
public override async Task GetMessages(
HelloRequest request,
IServerStreamWriter<HelloReply> responseStream,
ServerCallContext context)
{
for (int i = 1; i <= 5; i++)
{
await responseStream.WriteAsync(new HelloReply
{
Message = $"Message {i}"
});
await Task.Delay(1000);
}
}
Step 8: Error Handling in gRPC
gRPC uses status codes instead of HTTP status codes.
throw new RpcException(
new Status(StatusCode.InvalidArgument, "Invalid input"));
Common Status Codes:
OKInvalidArgumentNotFoundUnauthenticatedInternal
Step 9: Authentication & Security
gRPC supports:
Example: JWT authentication
builder.Services
.AddAuthentication("Bearer")
.AddJwtBearer();
gRPC vs REST – When NOT to Use gRPC
Avoid gRPC when:
- Public APIs for browsers
- SEO-dependent APIs
- Simple CRUD APIs
- Legacy systems without HTTP/2 support
Best Practices for gRPC in .NET
- Keep
.protofiles backward compatible - Use server streaming for large datasets
- Enable compression
- Add timeouts & retries
- Centralize
.protocontracts - Version services carefully
Conclusion
gRPC in .NET provides:
- High-performance communication
- Strong contracts
- Built-in streaming
- Excellent microservice support
For internal service-to-service communication, gRPC is often superior to REST.
If you're building scalable, distributed systems in .NET, gRPC should be part of your architecture toolkit.