Create a gRPC client and server in ExpressWebJs
Overview
ExpressWebjs version 4.2 comes with so many amazing features and the support for gRPC is one of them.
This tutorial shows how to create an ExpressWebJs gRPC client and Server. In the end, you’ll have a gRPC client that communicates with the gRPC Todo service.
In this tutorial, you:
✔️ Create a gRPC Server.
✔️ Create a gRPC client.
✔️ Test the gRPC client with the gRPC Todo service.
What is gRPC?
gRPC is an open-source Remote Procedure Call (RPC) framework developed initially by Google. It allows software applications to communicate with each other over a network, enabling them to invoke functions or methods in a remote system as if they were local. gRPC supports multiple programming languages and platforms, making it a versatile tool for building distributed systems. It uses the Protocol Buffers data serialization format for efficient and fast communication, and it also offers features such as load balancing, tracing, and authentication. gRPC is widely used for building microservices, client-server applications, and other distributed systems.
Project setting up
To install ExpressWeb, Make sure you have Nodejs and ts-node installed. Once that is done, you can use npx expresswebcli new
command, followed by your project name and --ts or --typescript to install your ExpressWeb Project.
--ts
or --typescript
flag enables Expresswebjs to generate the typescript version.
npx expresswebcli new myProjectName --typescript
Or you can use ts emplace of typescript
npx expresswebcli new myProjectName --ts
You can decide to install expresswebcli globally via npm like so:
npm install -g expresswebcli
Then run the below command to create your project.
expresswebcli new myProject --ts
Once that is done, move into your project directory or use the command below in your terminal.
cd myProjectName
Then install all dependencies by running npm install.
npm install
gRPC setup
We set up the gRPC host and port in the .env file
GRPC_HOST=127.0.0.1
GRPC_PORT=8082
Next will be to configure our service to run with gRPC. This is done in the app.ts in the project root directory.
/*
|---------------------------------------------------------------
| Http Server
|---------------------------------------------------------------
| This file bootstraps ExpressWebJs to start the Http server.
| Application Host, Port and Transfer Protocols are configured
| in the .env file. You are free to configure them.
|
*/
import { StartApp } from "expresswebcorets";
StartApp.withGRPC();
Creating proto files
We will create a Protos folder to house our proto files in App directory. Once that is done, we will then create Todo.proto file inside Protos folder.
syntax = "proto3";package Todo;service TodoService {
rpc GetAllTodos(Void) returns (TodoList) {}
}message Void{}message TodoModel {
string id = 1;
string name = 2;
string isCompleted=3;
string created_at = 4;
string updated_at = 5;
}message TodoList {
bool status = 1;
string message = 2;
repeated TodoModel data = 3;
}
Once our Todo.proto file is ready, we will add the path to gRPC config file in the Config folder in the root directory.
gRPC configuration file.
gRPC configuration file is located in the Config folder in the root directory.
import { GrpcRequest } from "Elucidate/Support/GRPC/GrpcRequest";
import { GrpcResponse } from "Elucidate/Support/GRPC/GrpcResponse";
import { Path } from "expresswebcorets/lib/Utils/Path";
export { GrpcRequest, GrpcResponse };
export default {
/*
|--------------------------------------------------------------------------
| gRPC Proto files
|--------------------------------------------------------------------------
| gRPC uses a contract-first approach to API development and Protocol
| buffers (protobuf) are used as the Interface Definition Language (IDL).
| Here you specify the path to your proto files
|
*/
protos: [Path("App/Protos/Todo.proto")], 👈 // Path to Todo.proto file.
//this accepts array of files
/*
|--------------------------------------------------------------------------
| gRPC Configuration option
|--------------------------------------------------------------------------
| Here you define gRPC Configuration Option
*/
options: {
keepCase: true,
longs: String,
enums: String,
arrays: true,
defaults: true,
oneofs: true,
},
};
gRPC implementation
Now we have our Todo.proto file ready, and gRPC configuration has been done. We can now move on to create the service implementation of our TodoService specified in our Todo.proto file.
Create a TodoController class, and add a method to fetch all todos from TodoRepository.
import { GrpcRequest, GrpcResponse } from "Config/grpc"; 👈 //import gRPC request and response
import { BaseController } from "./BaseController";
import {TodoRepository} from "App/Repository/TodoRepository"
export class TodoController extends BaseController {
constructor(private todoRepository:TodoRepository){} 👈 //inject TodoRepository
/**
* Display a listing of the resource.
* @method GET
* @endpoint
*/
public async getAllTodos(req: GrpcRequest, res: GrpcResponse) {
try{
const todos = await this.todoRepository.findAll();
return res.send({
status: true,
message: "Todos",
data: todos,
});
}catch(error){
return res.error({
code: grpc.status.UNAVAILABLE,
message: "Please try again later",
});
}
}
}
gRPC route
We can now create our gRPC route that will communicate the TodoController at the index method. This is done in the Route/api.ts file in the project root directory.
import { Route } from "Elucidate/Route/RouteManager";
/*
|--------------------------------------------------------------------------
| Api route
|--------------------------------------------------------------------------
|
| Here is where you can register your application routes. These
| routes are loaded by the RouteProvider. Now create something great!
|
*/
Route.grpc("TodoService", { GetAllTodos: "TodoController@getAllTodos" });
//--------------------------------------------------------------------------
export default Route.exec;
You can now use your gRPC client to load your proto file and connect to the server at http://127.0.0.1:8082