← назад к разделу

Когда один сервис зовёт другой сотни раз в секунду, накладные расходы REST начинают мешать: текстовый JSON надо сериализовать и парсить, заголовки повторяются, а контракт держится «на честном слове» — на документации, которая устаревает. gRPC решает именно эту задачу: строгий контракт, компактный бинарный формат и быстрый транспорт. Разберёмся, как он устроен и когда его стоит брать.

Что такое gRPC

gRPC — это способ вызывать метод чужого сервиса так, будто он локальный: вы пишете orders.Get(id), а под капотом уходит сетевой запрос. Такой подход называется RPC (remote procedure call, удалённый вызов процедуры). Google сделал gRPC поверх двух вещей:

  • protobuf (Protocol Buffers) — язык описания контракта и компактный бинарный формат данных;
  • HTTP/2 — транспорт с мультиплексированием и постоянными соединениями (разобран в статье про версии HTTP).

В отличие от REST, где вы думаете в терминах ресурсов и URL, в gRPC вы думаете в терминах сервисов и их методов.

Контракт в protobuf

Всё начинается с .proto-файла — это единый источник правды о контракте. В нём описаны сообщения (структуры данных) и сервис с методами:

syntax = "proto3";

message GetOrderRequest {
  string id = 1;
}

message Order {
  string id = 1;
  string status = 2;
  int64 amount = 3;   // в минимальных единицах, например копейках
}

service OrderService {
  rpc GetOrder(GetOrderRequest) returns (Order);
}

Числа = 1, = 2 — это не значения, а номера полей: именно они пишутся в бинарный формат вместо имён. Поэтому protobuf компактнее JSON (нет повторяющихся имён полей) и совместим при эволюции: добавить новое поле с новым номером можно, не сломав старых клиентов.

Кодогенерация: контракт превращается в код

Из .proto инструмент генерирует классы и заглушки на нужном языке — сервер реализует интерфейс, клиент получает готовый вызов. Правило простое: .proto — источник правды, код из него генерируется, а не пишется руками. Это и есть главное отличие от REST: контракт проверяется компилятором. Опечатку в имени поля вы поймаете при сборке, а не в проде.

Четыре вида вызовов

gRPC умеет не только «запрос-ответ». Всего есть четыре режима — за счёт стриминга HTTP/2:

  • Унарный — один запрос, один ответ. Как обычный вызов метода.
  • Серверный стриминг — один запрос, поток ответов. Например, «подпишись на обновления заказа».
  • Клиентский стриминг — поток запросов, один ответ. Например, загрузка данных частями.
  • Двунаправленный стриминг — оба конца шлют потоки одновременно. Например, чат или телеметрия.

Стриминг — то, что в REST приходится изобретать (long-polling, WebSocket, SSE), а в gRPC встроено.

Где это применяется

gRPC силён во внутренней связи между сервисами, где обе стороны ваши и важны скорость и строгий контракт:

  • Микросервисы, которые часто зовут друг друга: бинарный формат и переиспользуемые HTTP/2-соединения экономят время (о стоимости установки соединений — в статье про соединения и пулы).
  • Строго типизированные контракты между командами: .proto — общий язык, кодогенерация не даёт разойтись.
  • Потоковые сценарии: телеметрия, подписки, обмен событиями.

Где gRPC — плохой выбор:

  • Публичное API для браузеров и сторонних разработчиков. Браузер не умеет gRPC напрямую (нужен прокси grpc-web), а внешним потребителям привычнее REST + JSON, который видно глазами и легко потрогать curl'ом.
  • Отладка «на коленке». Бинарный формат не прочитать в логах без инструментов; REST-ответ читается сразу.
  • Кэширование HTTP. REST-GET кэшируется прокси и CDN из коробки; gRPC-вызов — нет.

Где спотыкаются начинающие:

  • Тащат gRPC в публичное API ради «скорости», получая мучения с браузерами и внешними клиентами. Для публичного контура REST почти всегда правильнее.
  • Меняют номера полей в .proto — это ломает совместимость. Номер поля неприкосновенен; поле можно только добавить с новым номером или пометить устаревшим.
  • Забывают про дедлайны и ретраи. Быстрый вызов не значит надёжный — сеть всё так же ненадёжна (см. таймауты и ретраи).
  • Ставят gRPC везде «потому что модно», хотя внутри всего пара вызовов в секунду — тогда выигрыш незаметен, а сложность добавилась.

Что учить дальше

gRPC — это одна развилка в проектировании контракта. Рядом — GraphQL, который решает другую боль (гибкие срезы данных для клиента), и базовый REST, от которого стоит отталкиваться по умолчанию. Транспортная основа gRPC — HTTP/2, а надёжность вызовов между сервисами — в статье про таймауты, ретраи и идемпотентность. Как выбор стиля вписывается в проектирование системы целиком — в разделе системного дизайна.