Microservice Nest JS using GRPC

Pritam Banerjee
4 min readOct 24, 2020

Nest JS is a very powerful and scalable framework which written in Typescript and it gives you lot of features to build modern miscroservice. We will use modern and latest GRPC technology which will use to build modern microservices. gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services. Nest JS works out of box with GRPC to build modern microservice which is very fast and it can scale very large apps.

Installation

To user GRPC with Nest JS you need to first install required packages for GRPC.

$ npm i --save grpc @grpc/proto-loader

To use GRPC in Nest JS you need to use grpc as transport layer, you select the gRPC transporter mechanism using the transport property of the options object passed to the createMicroservice() method. In the following example, we'll set up a sample service. The options property provides metadata about that service; its properties are described.

main.ts

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
transport: Transport.GRPC,
options: {
package: 'hero',
protoPath: join(__dirname, 'hero/hero.proto'),
},
});

In this file we have configured GRPC as transport layer in main.ts file and also you can see that we have added a sample hero proto file. So now the questions is what is proto file and why we needed it for GRPC. Proto files are the main building block for creating GRPC microservice architecture. In this proto file we write the types and reference of functions that we need to call from various microservices. So we will have proto files and where we will define the function names and then from each service are interact with them by calling those function and this the medium to use GRPC microservice.

Like many RPC systems, gRPC is based on the concept of defining a service in terms of functions (methods) that can be called remotely. For each method, you define the parameters and return types. Services, parameters, and return types are defined in .proto files using Google's open source language-neutral protocol buffers mechanism.

With the gRPC transporter, Nest uses .proto files to dynamically bind clients and servers to make it easy to implement remote procedure calls, automatically serializing and deserializing structured data.

Sample gRPC Service

Let’s define our sample gRPC service called HeroesService. In the above options object, theprotoPath property sets a path to the .proto definitions file hero.proto. The hero.proto file is structured using protocol buffers. Here's what it looks like:

// hero/hero.proto
syntax = "proto3";
package hero;service HeroesService {
rpc FindOne (HeroById) returns (Hero) {}
}
message HeroById {
int32 id = 1;
}
message Hero {
int32 id = 1;
string name = 2;
}

So in this section we defined one proto file where we have defined the types but this is not typescript types this types are defined in GRPC documentation and you can understand those types by going to GRPC documentation. As you can see we have created some types and a function which will use to connect and passed messages between two microservices in Nest JS.

Create Cotroller

Our HeroesService exposes a FindOne() method. This method expects an input argument of type HeroById and returns a Hero message (protocol buffers use message elements to define both parameter types and return types).

Next, we need to implement the service. To define a handler that fulfills this definition, we use the @GrpcMethod() decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

heroes.controller.ts

@Controller()
export class HeroesService {
@GrpcMethod()
findOne(data: HeroById, metadata: any): Hero {
const items = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Doe' },
];
return items.find(({ id }) => id === data.id);
}
}

You can also omit the first @GrpcMethod() argument. In this case, Nest automatically associates the handler with the service definition from the proto definitions file based on the class name where the handler is defined. For example, in the following code, class HeroesService associates its handler methods with the HeroesService service definition in the hero.proto file based on the matching of the name 'HeroesService'.

Client Register

Nest applications can act as gRPC clients, consuming services defined in .proto files. You access remote services through a ClientGrpc object. You can obtain a ClientGrpc object in several ways.

The preferred technique is to import the ClientsModule. Use the register() method to bind a package of services defined in a .proto file to an injection token, and to configure the service. The name property is the injection token. For gRPC services, use transport: Transport.GRPC. The options property is an object with the same properties described above.

imports: [
ClientsModule.register([
{
name: 'HERO_PACKAGE',
transport: Transport.GRPC,
options: {
package: 'hero',
protoPath: join(__dirname, 'hero/hero.proto'),
},
},
]),
];

After registering client now ee can simply call GRPC Proto file function from another service and how we can do that that code is given below.

app.service.ts

@Injectable()
export class AppService implements OnModuleInit {
@Client({
transport: Transport.GRPC,
options: {
package: 'hero',
protoPath: join(__dirname, 'hero/hero.proto'),
},
})
client: ClientGrpc;

private heroesService: HeroesService;

onModuleInit() {
this.heroesService = this.client.getService<HeroesService>('HeroesService');
}

getHero(): Observable<string> {
return this.heroesService.findOne({ id: 1 });
}
}

So in this way simply we can call GRPC service which is registered with an another microservice. If you follow this steps then you can create multiple microservices using GRPC and which will be connected using proto file functions this functions act as a messaging system which will connect each microservices. Also there are more advance scenario are there like GRPC streaming and ovsebale etc. So use GRPC today and create scalable microservices and use advance features for large real time projects.

--

--

Pritam Banerjee

I am Full Stack Developer and Data Scientist, I have worked some of the biggest client’s project (eg. Walmart, Cisco, Uber, Apple, JP Morgan, Capital One etc).