content: |
A simple and clean gRPC-based microservice built with Node.js, showcasing how to fetch user details with high performance and low latency.
gRPC (Google Remote Procedure Call) is a high-performance, open-source RPC framework that allows services to communicate efficiently, using:
-
π HTTP/2 (bi-directional streaming, multiplexing)
-
π¦ Protocol Buffers (Protobuf) for fast, typed serialization
-
π§ Contract-first design with
.protofilesFeature REST (Express.js) gRPC (Node.js) Protocol HTTP/1.1 HTTP/2 Data Format JSON (text-based) Protobuf (binary, compact) Contract Swagger (optional) .proto(enforced)Speed Slower π Faster (10x+) Streaming Manual (WebSockets) Native, full-duplex streaming Best for Public APIs Microservices/internal services grpc-user-service/ βββ protos/ β βββ user.proto βββ src/ β βββ server/ β β βββ index.js β β βββ service.js β β βββ loader.js β βββ client/ β β βββ index.js β β βββ loader.js β βββ config/ β βββ grpc.js βββ package.json βββ README.mdClient (index.js) β ββββΆ Calls GetUser({ id: "123" }) β Client Stub (loader.js) β Sends Protobuf request via HTTP/2 β Server receives request β Server Handler (service.js) β Processes and returns UserResponse β Client receives response βββ Logs or uses returned data
files:
- path: protos/user.proto
content: |
syntax = "proto3";
package user;
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}
message UserRequest {
string id = 1;
}
message UserResponse {
string name = 1;
string email = 2;
}
- path: src/server/index.js
content: |
const server = require('./loader');
server.start();
- path: src/server/loader.js
content: |
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const { implementUserService } = require('./service');
const PROTO_PATH = __dirname + '/../../protos/user.proto';
const packageDef = protoLoader.loadSync(PROTO_PATH);
const userProto = grpc.loadPackageDefinition(packageDef).user;
const server = new grpc.Server();
server.addService(userProto.UserService.service, implementUserService());
exports.start = () => {
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
console.log('β
gRPC Server started on 0.0.0.0:50051');
server.start();
});
};
- path: src/server/service.js
content: |
exports.implementUserService = () => ({
GetUser: (call, callback) => {
const { id } = call.request;
console.log('User ID:', id);
callback(null, {
name: "Amar Kumar",
email: "amar@example.com"
});
}
});
- path: src/client/index.js
content: |
const client = require('./loader');
client.GetUser({ id: "123" }, (err, res) => {
if (err) console.error(err);
else console.log('π§Ύ Response:', res);
});
- path: src/client/loader.js
content: |
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const PROTO_PATH = __dirname + '/../../protos/user.proto';
const packageDef = protoLoader.loadSync(PROTO_PATH);
const userProto = grpc.loadPackageDefinition(packageDef).user;
module.exports = new userProto.UserService(
'localhost:50051',
grpc.credentials.createInsecure()
);
- path: src/config/grpc.js
content: |
module.exports = {
GRPC_PORT: '0.0.0.0:50051',
GRPC_CREDENTIALS: require('@grpc/grpc-js').ServerCredentials.createInsecure()
};
## βοΈ Setup & Run
```bash
yarn install
node src/server/index.js # Start server
node src/client/index.js # Run client
```
## β
Sample Response
```json
{
"name": "Amar Kumar",
"email": "amar@example.com"
}
```