Understanding gRPC within .NET: High-Performance Communication Made Easy ✨🌐

Miguel Cardoso
4 min readJul 15, 2023

--

Introduction

If you’re a developer familiar with .NET and have heard about gRPC but are unsure about its specifics, you’ve come to the right place. In this blog post, we’ll dive into the world of gRPC within .NET and explore its powerful capabilities for high-performance communication. By the end, you’ll have a solid understanding of gRPC and how it can benefit your application development. Let’s get started! 🚀

What is gRPC?

gRPC is an open-source, high-performance remote procedure call (RPC) framework developed by Google. It enables efficient communication between services using a language-agnostic approach. gRPC utilizes Protocol Buffers (Protobuf) as its interface definition language and allows for both unary and streaming communication patterns. 💪

Setting Up a gRPC Server in .NET

To get started with gRPC in .NET, you’ll need to set up a gRPC server and install some nuggets.


dotnet add package Grpc.AspNetCore
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools

For a more in-depth tooling explanation please consider the official documentation.

Here’s a basic example of setting up a gRPC server using .NET 7’s top-level statements:

using Grpc.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);
// Add gRPC services
builder.Services.AddGrpc();
var app = builder.Build();
// Enable gRPC endpoints
app.UseRouting();
app.MapGrpcService<MyGrpcService>(); //Keep reading and all shall be answered
app.Run();

Defining gRPC Services and Messages

gRPC services and messages are defined using Protobuf. Protobuf provides a language-agnostic way to define the structure of messages and the services that operate on them. Here’s an example of a simple Protobuf message definition:

syntax = “proto3”;

message MyRequest {
string name = 1;
}
message MyResponse {
string message = 1;
}

service MyGrpc {
rpc MyMethod(MyRequest) returns (MyResponse); //one-off response like REST
rpc MyStreamingMethod(MyRequest) returns (stream MyResponse); //streams the response
}

The main takeaway is that we have Messages (message) and Services (service), we can think of a message as the DTO (data transfer object) and the services as the methods.

In this blog post we are not going to dive deep into protobuf syntax, thus for more information on designing and implementing Protobuf messages definitions I advise you to go the official documentation.

Implementing a gRPC Server in .NET

In the previous sections we saw how to setup a gRPC server and define services and messages, but what now ? How do we actually implement those MyGrpc services ?

Simple, the tooling auto-generates a bunch of code that we never really need to look at and as developers we need to only to _extend_ and implement the services that we defined.

Just like this 👇


using Grpc.Core;

public class MyGrpcService : MyGrpc.MyGrpcBase
{
public override Task<MyResponse> MyMethod(MyRequest request, ServerCallContext context)
{
// Implement your business logic here
// …
}
public override async Task MyStreamingMethod(MyRequest request, IServerStreamWriter<MyResponse> responseStream, ServerCallContext context)
{
// Implement your streaming logic here
// …
await responseStream.WriteAsync(new MyResponse { Message = “Response 1” });
await responseStream.WriteAsync(new MyResponse { Message = “Response 2” });
await responseStream.WriteAsync(new MyResponse { Message = “Response 3” });
// …
}
}

Implementing a gRPC Client in .NET

Once you have a gRPC server set up, you can implement a gRPC client in .NET to communicate with the server. Here’s an example of making a unary gRPC call and a streaming gRPC call from a client:

using Grpc.Net.Client;

//assuming your server is running in this port
var channel = GrpcChannel.ForAddress(“https://localhost:5001");
var client = new MyGrpc.MyGrpcClient(channel);

// Unary call
var request = new MyRequest { Name = “John” };
var response = await client.MyMethodAsync(request);
Console.WriteLine(response.Message);

// Streaming call
var streamingRequest = new MyRequest { Name = “Jane” };
using var streamingCall = client.MyStreamingMethod(streamingRequest);
await foreach (var streamingResponse in streamingCall.ResponseStream.ReadAllAsync())
{
Console.WriteLine(streamingResponse.Message);
}

gRPC vs. REST: Why Choose gRPC?

While REST has been the de facto standard for API communication, gRPC offers several advantages over REST in certain scenarios. Here are three key benefits of gRPC:

1. Efficiency: gRPC uses binary serialization with Protobuf, resulting in smaller payload sizes and reduced bandwidth consumption. It also benefits from the speed and multiplexing capabilities of HTTP/2, allowing for concurrent requests and efficient use of network resources. ⚡️💻

2. Strong Typing: gRPC uses Protobuf to define service interfaces and message structures. This enables strong typing and generates client and server code, providing compile-time safety and better integration with your development tools. ✅🔒 (Who doesn’t love types ?)

3. Streaming: gRPC supports both unary and streaming communication patterns. Streaming enables real-time updates, bidirectional communication, and efficient handling of large data sets. It’s well-suited for scenarios like real-time dashboards, collaborative editing, and IoT applications. 🌊📈

Final Remarks

Congratulations! You now have a solid understanding of gRPC within .NET and can start tinkering and understanding where it can really be helpful. We explored the basics, set up a gRPC server, defined services and messages using Protobuf, implemented the services and a gRPC client (including streaming), and discussed the advantages of gRPC over REST. With gRPC, you can unlock the power of efficient and high-performance communication in your .NET applications. Embrace gRPC and elevate your development capabilities! 💪🚀

But our journey doesn’t end here. To further deepen your knowledge and explore more advanced topics, we encourage you to go deeper, and get your “hands dirty”. Leave your thoughts in the comments section, ask questions, and share your experiences!

So, what are you waiting for? Start exploring, implementing, and leveraging the full potential of gRPC within .NET today! Happy coding! 💻🎉

--

--

Miguel Cardoso

Innovator and problem solver at heart. Product and Software Engineer exploring AI, software architecture and product management through writting.