gRPC для JavaScript (Node.js): библиотеки и примеры
gRPC — это высокопроизводительный фреймворк для удалённого вызова процедур (RPC), разработанный Google. Он использует Protocol Buffers (protobuf) для сериализации данных и HTTP/2 для транспорта. В экосистеме Node.js gRPC позволяет создавать быстрые и надёжные микросервисы с поддержкой двунаправленной потоковой передачи. В этой статье мы разберём основные библиотеки, установку и напишем рабочий пример сервера и клиента.
Основные библиотеки для gRPC в Node.js
Для работы с gRPC в среде Node.js существует несколько ключевых пакетов:
@grpc/grpc-js— чистая реализация gRPC на JavaScript. Не требует нативных зависимостей (C++), что упрощает установку. Рекомендуется для большинства современных проектов.@grpc/proto-loader— загрузчик файлов.proto. Преобразует protobuf-определения в объекты JavaScript для использования с@grpc/grpc-js.protobufjs— альтернативная библиотека для работы с protobuf. Поддерживает как статическую, так и динамическую генерацию кода.grpc-tools— CLI-инструменты для генерации JavaScript-кода из.protoфайлов (альтернатива динамической загрузке).
В этом руководстве мы будем использовать связку @grpc/grpc-js и @grpc/proto-loader — это современный и стабильный подход.
Установка зависимостей
Создайте новый проект и установите необходимые пакеты:
mkdir grpc-node-example
cd grpc-node-example
npm init -y
npm install @grpc/grpc-js @grpc/proto-loader
Определение сервиса через .proto файл
Создайте файл hello.proto с описанием сервиса и сообщений:
syntax = "proto3";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloStream (HelloRequest) returns (stream HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Здесь мы определили два метода: простой унарный SayHello и серверный стриминг SayHelloStream.
Реализация gRPC сервера на Node.js
Создайте файл server.js:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const PROTO_PATH = './hello.proto';
// Загружаем определение прото-файла
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;
// Реализация методов сервиса
function sayHello(call, callback) {
const name = call.request.name;
console.log(`Received request: ${name}`);
callback(null, { message: `Hello, ${name}!` });
}
function sayHelloStream(call) {
const name = call.request.name;
console.log(`Streaming for: ${name}`);
// Отправляем несколько ответов
for (let i = 0; i < 5; i++) {
call.write({ message: `Hello ${name} - message ${i + 1}` });
}
call.end();
}
// Запуск сервера
function main() {
const server = new grpc.Server();
server.addService(helloProto.Greeter.service, {
sayHello: sayHello,
sayHelloStream: sayHelloStream
});
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
console.log('gRPC server running on port 50051');
server.start();
});
}
main();
Реализация gRPC клиента на Node.js
Создайте файл client.js:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const PROTO_PATH = './hello.proto';
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;
function main() {
const client = new helloProto.Greeter('localhost:50051',
grpc.credentials.createInsecure());
// Унарный вызов
client.sayHello({ name: 'PythonLib' }, (error, response) => {
if (error) {
console.error('Error:', error);
return;
}
console.log('Unary response:', response.message);
});
//