Create a gRPC client and server in ASP.NET Core

Building Efficient APIs with gRPC and .NET Core Minimal API

In the world of modern software development, efficient communication between distributed systems is crucial. Enter gRPC, a cutting-edge framework that allows developers to build high-performance APIs using the power of Protocol Buffers (protobuf) and Remote Procedure Calls (RPC). In this tutorial, we’ll explore the basics of gRPC, understand how it differs from the traditional REST architecture, and walk through the process of creating a gRPC service and consuming it in a .NET Core Minimal API application.

gRPC and RPC

gRPC: gRPC (gRPC Remote Procedure Call) is a modern, open-source framework developed by Google. It facilitates communication between distributed systems by allowing applications to define services and message types using Protocol Buffers (protobuf) and generating code for various programming languages. gRPC focuses on performance, efficiency, and ease of use.

RPC (Remote Procedure Call)

RPC is a protocol that enables a computer program to execute code on another remote system as if it were a local function call. It abstracts the complexities of network communication and allows applications to communicate seamlessly across different devices and platforms. RPC allows you to call functions or procedures on remote servers in a way that appears similar to invoking local functions.

gRPC vs. RPC

  • Protocol: gRPC is an implementation of the RPC concept. However, gRPC uses modern technologies such as Protocol Buffers for serialization and HTTP/2 for communication, making it more efficient and powerful than traditional RPC implementations.

  • Efficiency: gRPC uses HTTP/2 for transport, which supports multiplexing, header compression, and other features that improve efficiency. This contrasts with traditional RPC, which might use older protocols that lack these optimizations.

  • Serialization: gRPC uses Protocol Buffers for serialization, which results in more compact and efficient data representation compared to traditional RPC’s use of XML or JSON.

Difference between gRPC and REST

REST (Representational State Transfer)

REST is an architectural style for designing networked applications, commonly used over HTTP. It uses HTTP methods (GET, POST, PUT, DELETE) to perform CRUD (Create, Read, Update, Delete) operations on resources represented by URLs. REST APIs often use JSON or XML for data serialization.


  1. Communication Protocol:

    • gRPC: Uses HTTP/2, a binary protocol that supports multiplexing and header compression.
    • REST: Primarily uses HTTP/1.1, which is text-based and lacks some efficiency features of HTTP/2.
  2. Serialization:

    • gRPC: Uses Protocol Buffers for efficient binary serialization.
    • REST: Typically uses JSON or XML for serialization, which is less compact and efficient compared to Protocol Buffers.
  3. Performance:

    • gRPC: Generally offers better performance due to binary serialization and HTTP/2 features.
    • REST: Can be less performant due to textual serialization and limitations of HTTP/1.1.
  4. Flexibility:

    • gRPC: Supports various programming languages and platforms, making it suitable for microservices.
    • REST: Widely supported across different platforms and devices.

Creating a gRPC Service in .NET Core

  1. Create a New Solution and Project:

    Open your terminal and navigate to the directory where you want to create the project.

    Run the following commands to create a new solution, a gRPC service project, and a gRPC client project using the .NET CLI:

dotnet new sln -n GrpcSolution
 dotnet new grpc -n GrpcService -o GrpcService
 dotnet new grpc -n GrpcClient -o GrpcClient
 dotnet sln add GrpcService/GrpcService.csproj
 dotnet sln add GrpcClient/GrpcClient.csproj
  1. Define the gRPC Service:

    Navigate to the GrpcService directory and locate the Protos folder. Inside it, find the .proto file and modify it to define your gRPC service and messages. For example:

    syntax = "proto3";
    import "google/protobuf/empty.proto";
    option csharp_namespace = "GrpcService.Protos";
    service TodoServiceGrpc {
        rpc AddTodo (TodoItem) returns (CreatedTodo);
        rpc GetTodos (google.protobuf.Empty) returns (stream TodoItem);
    message TodoItem {
        string id = 1;
        string title = 2;
        bool completed = 3;
    message CreatedTodo {
        int32 id = 1;

    Save the file.

  2. syntax = "proto3";: This line specifies that the Protocol Buffers version 3 syntax should be used for defining the messages and service in this .proto file.

  3. import "google/protobuf/empty.proto";: This line imports the empty.proto file from the google/protobuf package. The empty.proto file contains a message type named Empty, which represents an empty message. This message type is often used in gRPC service definitions to indicate that a particular RPC method does not require any input parameters. For example, the GetTodos method in the TodoServiceGrpc service does not need any input parameters, so it uses google.protobuf.Empty to represent that concept.

  4. option csharp_namespace = "GrpcService.Protos";: This line sets the C# namespace for the generated C# code. In this case, the generated classes for messages and services will be placed in the GrpcService.Protos namespace.

  5. service TodoServiceGrpc { ... }: This defines the gRPC service named TodoServiceGrpc. It contains two RPC methods:

    • rpc AddTodo (TodoItem) returns (CreatedTodo);: This declares an RPC method named AddTodo. It takes a TodoItem message as input and returns a CreatedTodo message as output. This method is used to add a new todo item.

    • rpc GetTodos (google.protobuf.Empty) returns (stream TodoItem);: This declares an RPC method named GetTodos. It takes no input parameters (using google.protobuf.Empty) and returns a stream of TodoItem messages. This method is used to retrieve a stream of all todo items.

  6. message TodoItem { ... }: This defines the TodoItem message type with three fields:

    • id: A string field representing the unique identifier for the todo item.
    • title: A string field representing the title or description of the todo item.
    • completed: A boolean field indicating whether the todo item is completed or not.
  7. message CreatedTodo { ... }: This defines the CreatedTodo message type with a single field:

    • id: An integer field representing the identifier of the created todo item. This message is returned when a new todo item is added using the AddTodo method.
  8. Generate C# Code:

    In the terminal, navigate to the GrpcService directory and run the following command to generate the C# code for your service and messages:

    cd GrpcService
    dotnet build
  9. Configure the Service Application:

    Open the Program.cs file in the GrpcService directory. Replace the existing code with the following:

  using GrpcService.Protos;
  using GrpcService.Services;
  using Microsoft.AspNetCore.Builder;
  using Microsoft.Extensions.DependencyInjection;
  var builder = WebApplication.CreateBuilder(args);
  var app = builder.Build();
  // Configure the HTTP request pipeline.
  app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit:");

How to consume the service in .net console app

Next Post Previous Post
No Comment
Add Comment
comment url