gRPC для TypeScript: библиотеки и примеры использования

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

gRPC для TypeScript: библиотеки и примеры

gRPC — это высокопроизводительный RPC-фреймворк от Google, работающий поверх HTTP/2 и использующий Protocol Buffers (protobuf) для сериализации данных. В TypeScript (и Node.js) gRPC позволяет строить эффективные микросервисные архитектуры с поддержкой стримов и двунаправленной связи. На этой странице мы разберём основные библиотеки, настройку рабочего окружения и напишем работающий пример клиент-серверного приложения.

Основные библиотеки для gRPC в TypeScript

Для работы с gRPC в экосистеме TypeScript существует три ключевых пакета:

  • @grpc/grpc-js — чистая JavaScript-реализация gRPC (без нативных зависимостей), полностью поддерживает HTTP/2 и работает в Node.js 12+.
  • @grpc/proto-loader — загрузчик .proto файлов, динамически создающий JavaScript-классы на основе определений protobuf.
  • ts-proto — генератор TypeScript-типов из proto-файлов. Альтернатива встроенному grpc-tools, но с лучшей поддержкой строгой типизации.

Установка всех компонентов одной командой:

npm install @grpc/grpc-js @grpc/proto-loader ts-proto
npm install -D typescript @types/node

Создание .proto файла

Начнём с определения сервиса. Создайте файл hello.proto:

syntax = "proto3";

package hello;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
  rpc SayHelloStream (HelloRequest) returns (stream HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Генерация TypeScript-типов с ts-proto

ts-proto создаёт полноценные интерфейсы и классы сообщений. Установите protoc и плагин:

npm install -g protoc-gen-ts-proto
protoc --ts_proto_out=./generated hello.proto

В результате получится файл generated/hello.ts с интерфейсами HelloRequest, HelloReply и типизированным сервисом GreeterClient.

Серверная часть (gRPC сервер на TypeScript)

Создайте файл server.ts:

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import { ProtoGrpcType } from './generated/hello';

const packageDef = protoLoader.loadSync('hello.proto');
const grpcObj = (grpc.loadPackageDefinition(packageDef) as unknown) as ProtoGrpcType;
const server = new grpc.Server();

server.addService(grpcObj.hello.Greeter.service, {
  SayHello: (call: any, callback: any) => {
    const name = call.request.name;
    callback(null, { message: `Привет, ${name}!` });
  },
  SayHelloStream: (call: any) => {
    const name = call.request.name;
    for (let i = 0; i < 5; i++) {
      call.write({ message: `Сообщение ${i + 1} для ${name}` });
    }
    call.end();
  }
});

server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
  console.log('Сервер запущен на порту 50051');
});

Клиентская часть (gRPC клиент на TypeScript)

Создайте файл client.ts:

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import { ProtoGrpcType } from './generated/hello';

const packageDef = protoLoader.loadSync('hello.proto');
const grpcObj = (grpc.loadPackageDefinition(packageDef) as unknown) as ProtoGrpcType;

const client = new grpcObj.hello.Greeter(
  'localhost:50051',
  grpc.credentials.createInsecure()
);

// Унарный вызов
client.SayHello({ name: 'Алиса' }, (err, response) => {
  if (!err) console.log('Ответ:', response?.message);
});

// Server-streaming вызов
const stream = client.SayHelloStream({ name: 'Боб' });
stream.on('data', (data) => console.log('Стрим:', data.message));
stream.on('end', () => console.log('Стрим завершён'));

Особенности работы с TypeScript

При использовании @grpc/proto-loader типы генерируются динамически, что может привести к потере строгой типизации. Рекомендуется:

  • Использовать ts-proto для статической генерации интерфейсов.
  • Применять

Рекомендаций