DEV Community

Luqman Bolajoko
Luqman Bolajoko

Posted on

Connecting NestJS and ASP.NET Core with gRPC: A Step-by-Step Guide

As microservices continue to grow in popularity, efficient communication between services becomes increasingly important. gRPC, a high-performance RPC framework, is ideal for such scenarios due to its support for language-agnostic, efficient binary serialization. In this article, we'll explore how to create a gRPC service in ASP.NET Core and consume it from a NestJS client.


1. Create the gRPC Service in ASP.NET Core

Step 1: Set Up an ASP.NET Core gRPC Service

First, create a new ASP.NET Core gRPC Service.

dotnet new grpc -n GrpcService
cd GrpcService
Enter fullscreen mode Exit fullscreen mode

Ensure you have the following package in your .csproj file:

<PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
Enter fullscreen mode Exit fullscreen mode

Step 2: Define the gRPC Service in Proto File

In the Protos folder, define your gRPC service and messages using the .proto format.

syntax = "proto3";

option csharp_namespace = "GrpcService";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Implement the gRPC Service

Now, implement the gRPC service in C# by overriding the SayHello method defined in the .proto file. Create a GreeterService.cs in your project:

public class GreeterService : Greeter.GreeterBase
{
    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = $"Hello, {request.Name}!"
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Configure ASP.NET Core for gRPC

In the Startup.cs file, configure your gRPC service:

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGrpcService<GreeterService>();

        // For gRPC-Web support:
        endpoints.MapGrpcWeb();
    });
}
Enter fullscreen mode Exit fullscreen mode

Run the ASP.NET Core gRPC service:

dotnet run
Enter fullscreen mode Exit fullscreen mode

Now, your gRPC service is running on https://localhost:5001.


2. Connect to the ASP.NET Core gRPC Service from a NestJS Client

Step 1: Set Up a NestJS Project

Create a new NestJS project to act as the client:

nest new grpc-client
cd grpc-client
Enter fullscreen mode Exit fullscreen mode

Step 2: Install gRPC and Protobuf Dependencies

To use gRPC in NestJS, you need to install the following dependencies:

npm install @nestjs/microservices grpc @grpc/proto-loader
Enter fullscreen mode Exit fullscreen mode

Step 3: Define the Proto File in NestJS

Copy the .proto file from the ASP.NET Core service and place it in the NestJS project, inside a protos folder. This ensures both the client and the server use the same contract.

Your protos/greet.proto file should look like this:

syntax = "proto3";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Configure the NestJS gRPC Client

In your app.module.ts, set up the NestJS gRPC client to connect to the ASP.NET Core service:

import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { join } from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'GREETER_PACKAGE',
        transport: Transport.GRPC,
        options: {
          url: 'localhost:5001',
          package: 'greeter',
          protoPath: join(__dirname, './protos/greet.proto'),
        },
      },
    ]),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Step 5: Create the NestJS Service and Controller

Create the service that will call the gRPC method:

import { Injectable } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { Observable } from 'rxjs';
import { OnModuleInit, Inject } from '@nestjs/common';

interface GreeterService {
  sayHello(data: { name: string }): Observable<{ message: string }>;
}

@Injectable()
export class AppService implements OnModuleInit {
  private greeterService: GreeterService;

  constructor(@Inject('GREETER_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.greeterService = this.client.getService<GreeterService>('Greeter');
  }

  sayHello(name: string): Observable<{ message: string }> {
    return this.greeterService.sayHello({ name });
  }
}
Enter fullscreen mode Exit fullscreen mode

In your app.controller.ts, create an endpoint that consumes the gRPC service:

import { Controller, Get, Query } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('hello')
  sayHello(@Query('name') name: string) {
    return this.appService.sayHello(name);
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Run the NestJS Client

Start the NestJS client:

npm run start
Enter fullscreen mode Exit fullscreen mode

Now, you can call http://localhost:3000/hello?name=NestJS from a browser or Postman. The NestJS client will call the ASP.NET Core gRPC service, which responds with a greeting message.


Best Practices for Connecting gRPC Services Across Platforms

  1. Shared Proto Files: Ensure that both services (ASP.NET Core and NestJS) use the same .proto file for compatibility.
  2. gRPC Communication: Since gRPC uses HTTP/2, make sure that both your client and server are running in environments that support HTTP/2.
  3. Security: Always use TLS (HTTPS) for gRPC communication, especially in production environments, to secure data transmission.
  4. Load Balancing: When scaling the ASP.NET Core gRPC service, implement load balancing mechanisms to distribute traffic efficiently.
  5. Error Handling: Handle gRPC errors properly, as they differ from traditional REST errors. Implement retry mechanisms and ensure that errors are communicated to clients clearly.

Conclusion

gRPC provides a powerful way to connect microservices across different platforms and languages. By using ASP.NET Core for the gRPC server and NestJS for the client, you can take advantage of gRPC’s performance and binary serialization to build fast, scalable, and reliable APIs.

Whether you're building a distributed system or integrating different services, gRPC offers an efficient communication model that scales well for both simple and complex use cases. Try it out in your next project and experience the power of cross-platform microservices!

Top comments (0)