Implementing gRPC in a .NET API (Step-by-Step Guide)


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:

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 .proto using 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 .proto file
  • 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:

  • OK
  • InvalidArgument
  • NotFound
  • Unauthenticated
  • Internal

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 .proto files backward compatible
  • Use server streaming for large datasets
  • Enable compression
  • Add timeouts & retries
  • Centralize .proto contracts
  • 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.

0 Comments Report