🔥 Build an RPC API with Node JS

RPC (Remote Procedure Call) is a powerful and efficient way to build APIs for microservices and other distributed systems. In this post, I will show you how to build an RPC API using Node.js and the gRPC framework.

What is gRPC?

gRPC is an open-source framework developed by Google for building high-performance, scalable, and efficient APIs using the Protocol Buffers data serialization format and the HTTP/2 protocol. It supports multiple languages, including Node.js, and is designed for use in microservices and other distributed systems.

Setting up the project

To get started, you will need to have Node.js and npm (Node Package Manager) installed on your machine. Once you have those set up, you can create a new Node.js project and install the gRPC package.

$ mkdir my-rpc-api
$ cd my-rpc-api
$ npm init -y
$ npm install --save grpc

Defining the service

The first step in building an RPC API is to define the service. This is done using a Protocol Buffers file, which is a file that describes the service's methods and their input and output types.

Here's an example of a simple service definition:

syntax = "proto3";

service ExampleService {
  rpc add (AddRequest) returns (AddResponse) {}
}

message AddRequest {
  int32 a = 1;
  int32 b = 2;
}

message AddResponse {
  int32 result = 1;
}

This service has one method, called "add", which takes an AddRequest message and returns an AddResponse message. The AddRequest message has two fields, "a" and "b", which are both integers. The AddResponse message has one field, "result", which is also an integer.

Implementing the service

Once the service is defined, you can implement it in Node.js. Here's an example of how you might implement the "add" method from the previous example:

const grpc = require('grpc');

const proto = grpc.load('example.proto');
const examplePackage = proto.example;

const server = new grpc.Server();
server.addService(examplePackage.ExampleService.service, {
  add: (call, callback) => {
    const a = call.request.a;
    const b = call.request.b;
    const result = a + b;
    callback(null, { result });
  },
});

server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
server.start();

In this example, we first load the protobuf definition file (example.proto) and use it to create an instance of the service. Then we create a new gRPC server and add our service to it. Finally, we start the server, listening on the address and port of your choice.

Creating the client

To call the service from a client, you will also need to generate the client code from the protobuf definition file. This can be done using the protoc compiler, which is included with the gRPC package.

$ protoc example.proto --js_out=import_style=commonjs,binary:.

This will generate a file called example_pb.js in the current directory, which contains the client code for the service.

Here's an example of how you might use the client code to call the "add" method from the previous example:

const grpc = require('grpc');
const proto = grpc.load('./example.proto');
const examplePackage = proto.example;

const client = new examplePackage.ExampleService('localhost:50051', grpc.credentials.createInsecure());

const request = new examplePackage.AddRequest();
request.setA(2);
request.setB(3);

client.add(request, (error, response) => {
    if (!error) {
        console.log("Result :", response.getResult())
    } else {
        console.log("Error :", error)
    }
});

In this example, we first load the protobuf definition file and use it to create an instance of the client. Then we create an instance of the AddRequest message, set the values of the "a" and "b" fields, and call the "add" method on the client. The callback function will be invoked with the result or an error, if any.

Conclusion

In this post, we've shown you how to build an RPC API using Node.js and the gRPC framework. We've covered the basics of defining the service using Protocol Buffers, implementing the service in Node.js, and creating the client. While this is a simple example, gRPC offers many more advanced features such as bi-directional streaming and flow control, which can be used to build more complex and powerful APIs.

← Go home