When building microservices or modern distributed applications, APIs are the backbone of communication between services. Traditionally, REST APIs have dominated the web, but in recent years, gRPC (Google Remote Procedure Call) has gained significant traction, especially in systems where speed, scalability, and bi-directional communication are critical.
gRPC is a high-performance, open-source RPC framework developed by Google. It’s designed for efficient communication between services, especially in microservices-based architectures.
One of the core components of gRPC is Protocol Buffers (Protobuf) — a language-neutral, platform-neutral way of serializing structured data. You can think of Protobuf as a rulebook that defines the contract between the client and server.
REST APIs have been around for decades and are the default choice for web applications. They are:
Easy to implement
Widely supported
Secure and familiar
However, REST is tied to HTTP/1.1, where each new request requires a new connection. In high-throughput systems, this can introduce unnecessary overhead and reduce efficiency.
Unlike REST, gRPC is built on HTTP/2, which brings several key benefits:
Persistent connection → A single connection can handle multiple requests and responses.
Streaming support → Clients and servers can send multiple messages over the same connection.
Smaller payloads → Protobuf is more compact than JSON, leading to faster serialization and deserialization.
Bi-directional communication → Perfect for real-time apps like chat, collaboration tools, or streaming services.
📌 Example: In a chat application, gRPC allows a client to send messages continuously and receive responses instantly over the same session — no need to re-establish a connection for every message.
Here’s how you might expose a simple Hello World endpoint using a REST API with Express.js:
const express = require('express');
const app = express();
const port = 3000;
app.get('/hello/:name', (req, res) => {
const name = req.params.name;
res.json({ message: `Hello, ${name}!` });
});
app.listen(port, () => {
console.log(`REST API server running at http://localhost:${port}`);
});
To test, open a browser or run:
http://localhost:3000/hello/usebruno
Response:
{ "message": "Hello, usebruno!" }
With gRPC, you define the service in a .proto file and generate code from it.
syntax = "proto3";
service HelloService {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDef = protoLoader.loadSync('hello.proto');
const grpcObj = grpc.loadPackageDefinition(packageDef);
const server = new grpc.Server();
server.addService(grpcObj.HelloService.service, {
SayHello: (call, callback) => {
const name = call.request.name;
callback(null, { message: `Hello, ${name}!` });
}
});
server.bindAsync(
'0.0.0.0:50051',
grpc.ServerCredentials.createInsecure(),
() => {
console.log("gRPC server running at http://localhost:50051");
server.start();
}
);
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDef = protoLoader.loadSync('hello.proto');
const grpcObj = grpc.loadPackageDefinition(packageDef);
const client = new grpcObj.HelloService(
'localhost:50051',
grpc.credentials.createInsecure()
);
client.SayHello({ name: "usebruno" }, (err, response) => {
if (err) console.error(err);
else console.log(response.message);
});
To test, run the server and client:
node server.js
node client.js
Response:
Hello, usebruno!
We at Bruno recently released support for gRPC in beta mode. You can test, debug and perform streaming operations for gRPC, including unary, server, client and bidirectional streaming.
You can add a .proto file at the collection and individual request level to reflect server methods automatically in Bruno.
The Bruno gRPC interface provides a familiar, intuitive experience for working with gRPC services.
Per-request proto file support: Attach a .proto
file at the request level to define the service and message structures.
Method auto-suggestion: When composing a request, Bruno automatically suggests available methods in the response section based on the attached proto file.
Pre-built message autofill: Use the Auto Fill button to quickly populate fields with pre-built message templates when sending a request.
Note: The gRPC feature is currently in beta. You can learn more about it in the official Bruno documentation.
To start using the gRPC feature in Bruno:
Open Preferences in Bruno.
Go to the Beta section.
Enable the gRPC Support option.
Once enabled, you can create, test, and debug gRPC requests directly within Bruno, just like you would with REST requests.
Once you enable the gRPC support from Preferences > Beta, you create a gRPC request with the following steps:
Your gRPC endpoint is visible in Bruno now to send, debug and test requests.
You can add proto files in the gRPC interface at two levels:
You can add the proto file individually at the request level for method discovery.
.proto
files from your local systemAdding proto files at the collection level reduces the redundant steps at once and uses multiple.
.proto
files from your local system
gRPC streaming allows you to send and receive multiple messages over a single connection, making it ideal for:
Feel free to read more about streaming with examples from Bruno's official documentation.
We’ve published the full working collection on GitHub. You can either clone this or simply click the Fetch in Bruno button below!
REST APIs remain a great choice for public APIs, simple web apps, and when human readability and wide adoption matter most. gRPC shines in microservices, real-time apps, and high-performance systems, where speed, efficiency, and streaming are critical.
Bruno’s gRPC support lets you test, debug, and validate your gRPC APIs without requiring login or credentials. Download Bruno, start exploring gRPC, and share your feedback!