gRPC (Google Remote Procedure Call) is a high-performance, open-source and language-agnostic RPC (Remote Procedure Call) framework developed by Google. It allows you to build efficient, scalable APIs that communicate across different services in various programming languages. Unlike traditional REST APIs that use HTTP/JSON, gRPC uses HTTP/2 and Protocol Buffers (protobufs) for better performance and efficient serialization.
In this blog post, we’ll show you how to create a gRPC API in Node.js. We’ll go through the basics of setting up a gRPC server, defining services with Protocol Buffers, and interacting with the API using a Node.js client.
Table of Contents
Why Use gRPC?
Before we dive into the code, let’s briefly discuss why you might choose gRPC over REST for certain applications:
- Performance: gRPC uses HTTP/2, which provides multiplexing, header compression, and efficient connection reuse, resulting in lower latency and faster communication.
- Strongly Typed Contracts: With gRPC, the service definitions are defined using Protocol Buffers (protobufs), providing a strongly-typed schema that ensures both the client and server agree on the data format.
- Cross-Language Compatibility: gRPC supports multiple programming languages (like JavaScript, Python, Go, Java, and more), making it easy to create cross-language microservices.
- Streaming: gRPC supports bidirectional streaming, making it ideal for real-time applications like chat systems, live updates, and video streaming.
Steps to Create a gRPC API in Node.js
Let’s walk through the process of building a gRPC API in Node.js step by step.
1. Setting Up Your Project
First, let’s set up a basic Node.js project and install the necessary dependencies.
1.1 Initialize a New Node.js Project
To create gRPC API in node.js, Create a new directory for your project and initialize a new Node.js application:
mkdir grpc-api
cd grpc-api
npm init -y
1.2 Install Dependencies
To work with gRPC in Node.js, you’ll need to install the following dependencies:
- grpc: The official Node.js gRPC library.
- @grpc/proto-loader: A utility to load
.proto
files.
Install them with npm:
npm install grpc @grpc/proto-loader
2. Defining Your gRPC Service
gRPC services are defined using Protocol Buffers (protobufs), a language-neutral, platform-neutral interface definition language (IDL). In this step, we’ll define a simple Greeter
service with a SayHello
method.
2.1 Create a .proto
File
In your project, create a new folder named protos
to store the Protocol Buffers files:
mkdir protos
Inside the protos
folder, create a file called helloworld.proto
:
// protos/helloworld.proto
syntax = "proto3";
package helloworld;
// The Greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
Explanation of the helloworld.proto
file:
syntax = "proto3";
specifies that we’re using version 3 of the Protocol Buffers syntax.- The
Greeter
service has a methodSayHello
that takes aHelloRequest
message and returns aHelloReply
message. HelloRequest
contains aname
field, whileHelloReply
contains amessage
field.
2.2 Compile the Proto File
In gRPC API in node.js, the .proto
file needs to be compiled into code that can be used by the server and client. While Node.js doesn’t require direct compilation of .proto
files (as in other languages like Java or Go), we need to load the proto definition dynamically.
We’ll use the @grpc/proto-loader
package to load and parse the .proto
file. So, we don’t need to compile it manually, but we do need to load it when creating the server.
3. Creating the gRPC Server
Now, let’s create the gRPC server that will implement the SayHello
method from the Greeter
service.
3.1 Create server.js
In your project’s root directory, create a server.js
file:
// server.js
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
// Load the proto file
const PROTO_PATH = './protos/helloworld.proto';
const packageDefinition = protoLoader.loadSync(PROTO_PATH);
const grpcObject = grpc.loadPackageDefinition(packageDefinition);
const helloworld = grpcObject.helloworld;
// Implement the SayHello method
function sayHello(call, callback) {
const greeting = `Hello, ${call.request.name}`;
callback(null, { message: greeting });
}
// Create and start the gRPC server
const server = new grpc.Server();
server.addService(helloworld.Greeter.service, { SayHello: sayHello });
// Bind the server to a port
const port = '50051';
server.bind(`127.0.0.1:${port}`, grpc.ServerCredentials.createInsecure());
console.log(`Server running at http://127.0.0.1:${port}`);
// Start the server
server.start();
Explanation of server.js
:
- We load the
.proto
file using@grpc/proto-loader
and then load it usinggrpc.loadPackageDefinition()
. - We define the
sayHello
function, which is the implementation of theSayHello
RPC. It receives acall
object and acallback
function. Thecall.request
contains the data sent by the client, and we use thecallback
to send the response. - The gRPC server is created using
new grpc.Server()
. We then add theGreeter
service to the server usingserver.addService()
, passing theSayHello
function as the handler. - The server is bound to
127.0.0.1:50051
, and the server starts running on that address and port.
4. Creating the gRPC Client
To interact with the server, we need a client that sends a request to the SayHello
method.
4.1 Create client.js
In your project’s root directory, create a client.js
file:
// client.js
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
// Load the proto file
const PROTO_PATH = './protos/helloworld.proto';
const packageDefinition = protoLoader.loadSync(PROTO_PATH);
const grpcObject = grpc.loadPackageDefinition(packageDefinition);
const helloworld = grpcObject.helloworld;
// Create a client instance
const client = new helloworld.Greeter('localhost:50051', grpc.credentials.createInsecure());
// Call the SayHello method
client.SayHello({ name: 'World' }, (error, response) => {
if (!error) {
console.log('Greeting:', response.message);
} else {
console.error(error);
}
});
Explanation of client.js
:
- We load the
.proto
file in the same way as the server. - We create a
client
instance using theGreeter
service. The client connects to the server atlocalhost:50051
(the address where the server is running). - We then call the
SayHello
method, passing a request object{ name: 'World' }
. The server responds with a greeting message, which we log to the console.
5. Running the Server and Client
5.1 Start the gRPC Server
In the terminal, run the server:
node server.js
You should see the following output:
Server running at http://127.0.0.1:50051
5.2 Run the gRPC Client
In a separate terminal window, run the client:
node client.js
You should see the following output:
Greeting: Hello, World
6. Conclusion
You’ve just built a simple gRPC API in Node.js! Here’s a summary of what we’ve done:
- Created a
.proto
file to define the service and messages. - Implemented the server using the gRPC and
@grpc/proto-loader
libraries. - Created a client that communicates with the server and calls the
SayHello
RPC method. - Tested the server and client by running them locally and receiving a greeting message.
gRPC provides a fast, efficient, and strongly-typed way to build APIs, especially for microservices or when performance is critical. You can extend this example by adding more complex RPC methods, streaming, authentication, and more.
Happy coding!
How to Create a Web Service in Node.js: A Beginner’s Guide