Building High-Performance APIs with gRPC in .NET Core 9

Building High-Performance APIs with gRPC in .NET Core 9


Introduction


gRPC (Google Remote Procedure Call) is a high-performance, open-source RPC framework designed for efficient communication between services. It offers faster response times, low bandwidth usage, and strongly typed contracts, making it a great alternative to REST APIs for microservices and real-time applications.


In this article, we will explore how to set up and use gRPC in .NET Core 9, covering key concepts, implementation steps, and best practices.



---


Why Use gRPC?


✔ High Performance: Uses HTTP/2 for multiplexing, compression, and lower latency.

✔ Strong Typing: Uses Protocol Buffers (Protobuf) instead of JSON, ensuring data integrity.

✔ Streaming Support: Supports unary, client-streaming, server-streaming, and bi-directional streaming.

✔ Better Efficiency: Uses binary serialization (Protobuf), reducing payload size compared to JSON.

✔ Language Agnostic: Supports multiple languages like C#, Java, Python, and Go.



---


Setting Up gRPC in .NET Core 9


Step 1: Create a gRPC Project


Open a terminal and run:


dotnet new grpc -n GrpcServiceDemo

cd GrpcServiceDemo

dotnet build


This will create a gRPC service project with the following structure:


GrpcServiceDemo/

│── Protos/

│ └── greet.proto

│── Services/

│ └── GreeterService.cs

│── appsettings.json

│── Program.cs

│── Startup.cs (for older versions)



---


Step 2: Define a gRPC Service (Protobuf File)


Inside the Protos folder, open greet.proto and define the service:


syntax = "proto3";


option csharp_namespace = "GrpcServiceDemo";


service Greeter {

  rpc SayHello (HelloRequest) returns (HelloReply);

}


message HelloRequest {

  string name = 1;

}


message HelloReply {

  string message = 1;

}


Explanation:


Defines a Greeter service with a single method SayHello().


HelloRequest is the input message containing a name field.


HelloReply is the response message containing a message field.




---


Step 3: Implement the gRPC Service in C#


Open Services/GreeterService.cs and modify it:


using System.Threading.Tasks;

using Grpc.Core;

using GrpcServiceDemo;


public class GreeterService : Greeter.GreeterBase

{

    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)

    {

        return Task.FromResult(new HelloReply

        {

            Message = $"Hello, {request.Name}!"

        });

    }

}


Explanation:


Greeter.GreeterBase is generated from greet.proto and provides the base class.


SayHello() implements the gRPC method, responding with a greeting message.




---


Step 4: Configure gRPC in .NET Core 9


Modify Program.cs:


var builder = WebApplication.CreateBuilder(args);


builder.Services.AddGrpc();


var app = builder.Build();


app.MapGrpcService<GreeterService>();


app.MapGet("/", () => "gRPC Service is running. Use a gRPC client to communicate.");


app.Run();


Key Points:

✔ Registers gRPC services using builder.Services.AddGrpc().

✔ Maps the GreeterService using app.MapGrpcService<GreeterService>().

✔ Adds a fallback endpoint for browser requests.



---


Step 5: Running the gRPC Server


Run the application:


dotnet run


By default, gRPC will run on https://localhost:5001.



---


Creating a gRPC Client in .NET Core 9


To test the gRPC service, let's create a gRPC client.


Step 1: Create a .NET Console App


dotnet new console -n GrpcClientDemo

cd GrpcClientDemo

dotnet add package Grpc.Net.Client

dotnet add package Google.Protobuf

dotnet add package Grpc.Tools



---


Step 2: Add Protobuf Reference


Modify GrpcClientDemo.csproj to include:


<ItemGroup>

    <Protobuf Include="../GrpcServiceDemo/Protos/greet.proto" GrpcServices="Client" />

</ItemGroup>


This will auto-generate the client classes from the Protobuf file.



---


Step 3: Implement the gRPC Client


Modify Program.cs:


using System;

using System.Threading.Tasks;

using Grpc.Net.Client;

using GrpcServiceDemo;


class Program

{

    static async Task Main(string[] args)

    {

        using var channel = GrpcChannel.ForAddress("https://localhost:5001");

        var client = new Greeter.GreeterClient(channel);


        var request = new HelloRequest { Name = "John" };

        var response = await client.SayHelloAsync(request);


        Console.WriteLine("Server Response: " + response.Message);

    }

}


Explanation:

✔ GrpcChannel.ForAddress() creates a secure connection to the gRPC server.

✔ GreeterClient calls the SayHello() method.

✔ The response is displayed in the console.



---


Step 4: Run the gRPC Client


Start the server first:


cd GrpcServiceDemo

dotnet run


Then, run the client in another terminal:


cd GrpcClientDemo

dotnet run


Output:


Server Response: Hello, John!



---


gRPC Streaming in .NET Core 9


gRPC supports streaming, allowing efficient real-time data transfer.


Example: Server Streaming


Modify greet.proto:


service Greeter {

  rpc SayHelloStream (HelloRequest) returns (stream HelloReply);

}


Modify GreeterService.cs:


public override async Task SayHelloStream(

    HelloRequest request, 

    IServerStreamWriter<HelloReply> responseStream, 

    ServerCallContext context)

{

    for (int i = 0; i < 5; i++)

    {

        await responseStream.WriteAsync(new HelloReply 

        { 

            Message = $"Hello {request.Name}, message {i + 1}" 

        });

        await Task.Delay(1000);

    }

}


Modify Program.cs in the client:


using var channel = GrpcChannel.ForAddress("https://localhost:5001");

var client = new Greeter.GreeterClient(channel);


using var call = client.SayHelloStream(new HelloRequest { Name = "John" });


await foreach (var response in call.ResponseStream.ReadAllAsync())

{

    Console.WriteLine("Received: " + response.Message);

}


Now, the client will receive multiple messages asynchronously from the server.



---


Conclusion


gRPC in .NET Core 9 is a powerful tool for building high-performance, scalable, and real-time APIs. It outperforms REST in scenarios requiring low latency, real-time streaming, and strongly typed contracts.


Key Takeaways:


✔ gRPC is faster and more efficient than REST.

 Uses Protocol Buffers (Protobuf) for compact, strongly typed data exchange.

✔ Supports unary, streaming, and bi-directional communication.

✔ Ideal for microservices, IoT, and real-time applications.

Comments

Popular posts from this blog

Maxpooling vs minpooling vs average pooling

Understand the Softmax Function in Minutes

Percentiles, Deciles, and Quartiles