gRPC API
All about GRPC
Before learning gRPC, we need to understand what is RPC (Remote Procedure Call) and how it differs from Local Procedure Call.
What is RPC
RPC (Remote Procedure Call) is a function call that runs in another process, usually in another machine.
A function like:
user = getUserById(42)gRPC
gRPC is a high-performance RPC framework created at Google and open sourced in 2015.
gRPC doesn't use JSON, it uses Protocol Buffers (called Protobuf).
Why not JSON? JSON is readable but machine doesn't need readable text. They need fast and compact data like Protobuf.
Protobuf is a binary format which means much smaller sizes, much faster serialization, strong typing.
You can define your data structures and services methods in a .proto file and gRPC generates the code automatically for different languages.
JSON vs Protobuf
// JSON
{
"id": 0,
"name": "",
"active": false
}// Protobuf
message User = {
int32 id = 1;
string name = 2;
bool active = 3;
}The way Protobuf works is it simply:
- take a data object
- convert it into a tiny binary format
- send it over the network
- server rebuilds the same data object and sends response back using the same Protobuf process.
This ensures both client and server speaks the exact same data structure.
Because all of this is generated from .proto files, you don't actually write any networking code. gRPC handles serialization, routing, and communication. Using gRPC feels just like calling a normal function that your backend understands.
Benefits of using gRPC:
-
gRPC runs on top of HTTP/2 instead of HTTP/1.1
HTTP/1.1 requests needs its own TCP connection and they often get stuck waiting each other causing delay and bottlenecks.
But HTTP/2 fixes all of this. It allows serveral requests travel over a single TCP connection reducing latency and blocking.
This feature makes gRPC perfect for high-speed real-time communication.
-
Speed
Protobuf messages are tiny compared to JSON.
-
Less CPU Usage
Since gRPC uses binary format, then binary serialization to send over the network is much cheaper than JSON.
-
Low Latency
With gRPC, you get low latency since HTTP/2 requests don't block each other like in HTTP/1.1.
-
Less Bandiwth
Payloads in gRPC are far smaller than JSON.
When not to use gRPC:
- Public APIs
- Browser doesn't support gRPC natively, must install extra packages
When to use gRPC:
- Communicating between internal services written in different languages (microservices)
Building gRPC APIs
Install dependencies.
npm install @grpc/grpc-js @grpc/proto-loaderDefine a proto file.
syntax = "proto3";
package user;
service UserService {
rpc GetUser (GetUserRequest) returns (User);
}
message GetUserRequest {
int32 id = 1;
}
message User {
int32 id = 1;
string email = 2;
string name = 3;
}Create RPC server.
import grpc from '@grpc/grpc-js';
import protoLoader from '@grpc/proto-loader';
const packageDef = protoLoader.loadSync('user.proto');
const proto = grpc.loadPackageDefinition(packageDef).user;
function getUser(call, callback) {
const user = {
id: call.request.id,
email: 'jose@example.com',
name: 'Jose',
};
callback(null, user);
}
const server = new grpc.Server();
server.addService(proto.UserService.service, { getUser });
server.bindAsync(
'0.0.0.0:50051',
grpc.ServerCredentials.createInsecure(),
() => server.start()
);Create the gRPC client.
import grpc from '@grpc/grpc-js';
import protoLoader from '@grpc/proto-loader';
const packageDef = protoLoader.loadSync('user.proto');
const proto = grpc.loadPackageDefinition(packageDef).user;
const client = new proto.UserService(
'localhost:50051',
grpc.credentials.createInsecure()
);
client.getUser({ id: 42 }, (err, response) => {
console.log(response);
});