Ваша команда пилит новый сервис. Самый умный разработчик приносит бенчмарк: «gRPC в десять раз быстрее». Другой резонно спрашивает: и что, теперь надо выкинуть Postman, Swagger и привычный JSON? Так выбор между gRPC и REST быстро превращается в ломание копий.
Спойлер: победителя не будет. REST удобен браузеру и внешним интеграторам, gRPC — частым межсервисным вызовам и потокам. Давайте разберёмся, в чём разница и что выбирать под разные задачи.
ВАМ ПРИШЛО ПРИГЛАШЕНИЕ 💌
Приходите к нам в соцсети поделиться своим мнением и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте — шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!
Что такое gRPC и REST
REST — архитектурный стиль работы с ресурсами через HTTP: например, GET /users/42 получает пользователя. REST API часто передаёт данные в JSON, хотя сам REST не требует именно этот формат.
gRPC — фреймворк удалённых вызовов: клиент вызывает метод удалённого сервиса почти как обычную функцию. Контракт описывают в .proto, из него генерируются клиентские и серверные заготовки, а сообщения обычно передаются в бинарном Protocol Buffers, или protobuf, поверх HTTP/2.
REST задаёт архитектурный подход, а gRPC — RPC-модель с контрактом и кодогенерацией. gRPC создан в Google; на октябрь 2026 года он остаётся проектом CNCF Incubating. Поддерживаются в том числе Go, Java, C++ и Python. Для Rust в 2026 году вышел preview клиента, серверная часть ещё разрабатывается.
Базовую механику REST мы разбирали в материале Как устроены API: разбираемся на примере REST API.
Как работают gRPC и REST
Путь REST-запроса
Для пользователя 42 клиент выбирает метод и URL, добавляет заголовки и отправляет запрос. Сервер отвечает HTTP-статусом и, например, JSON.
Запрос: GET /users/42
{
"id": 42,
"name": "Ada Lovelace",
"email": "ada@example.com"
}
JSON — текстовый формат, поэтому ответ видно в DevTools, curl или Postman. Подробнее — в материале JSON: что это за формат и как с ним работать. REST API может работать поверх HTTP/1.1 или HTTP/2, а результат запроса выражается обычным HTTP-кодом: 200, 404, 500 и так далее.
Путь gRPC-вызова
В gRPC сначала описывают сервис в .proto. Для того же GetUser контракт может выглядеть так:
protobuf
// Указываем синтаксис Protocol Buffers.
syntax = "proto3";
// Задаём пространство имён.
package users.v1;
// Описываем запрос.
message GetUserRequest {
// Передаём идентификатор пользователя.
int32 id = 1;
}
// Описываем ответ.
message User {
// Возвращаем идентификатор, имя и почту.
int32 id = 1;
string name = 2;
string email = 3;
}
// Объявляем сервис.
service UserService {
// Связываем запрос и ответ с методом.
rpc GetUser(GetUserRequest) returns (User);
}
Генератор создаёт клиент и серверные заготовки. GetUser() сериализуется protobuf и уходит по HTTP/2 с метаданными. Финальный grpc-status приходит в трейлерах — как чек после покупки: тело ответа закончилось, а итог вызова приходит следом.
gRPC против REST
Сравним gRPC и REST по основным параметрам. Один и тот же параметр может быть полезен для внутреннего сервиса и неудобен для публичного API.
| Параметр | REST | gRPC |
| Контракт | Обычно OpenAPI рядом с кодом | .proto как исходная схема |
| Формат | Часто JSON | Обычно protobuf |
| Транспорт | HTTP/1.1 или HTTP/2 | HTTP/2 |
| Стриминг | SSE, WebSocket, длинные опросы | Четыре типа RPC |
| Браузер | Работает напрямую | gRPC-Web, Connect или gateway |
| Ручная отладка | curl, Postman, DevTools | grpcurl, .proto, серверная рефлексия |
| HTTP-кеш | GET, Cache-Control, ETag | Стандартные RPC идут через POST |
| Порог входа | HTTP и JSON знакомы веб-командам | Нужны .proto и кодогенерация |
| Зрелость инструментов | HTTP/OpenAPI поддерживают браузеры, прокси и большинство веб-стеков | Официальные SDK покрывают основные языки; ручные инструменты обычно требуют схему или рефлексию |
В споре gRPC против REST не смешивайте gRPC и protobuf. Protobuf отвечает за схему и сериализацию, gRPC — за вызовы и транспорт. HTTP-кеш переносится не напрямую: стандартные RPC идут через POST и собственные статусы.
Откуда берётся выигрыш в скорости
Производительность gRPC складывается из нескольких деталей. Protobuf передаёт номера полей вместо имён — как если бы вместо названий столбцов пересылали их номера. Бинарное сообщение обычно компактнее JSON и не требует разбора текста.
HTTP/2 умеет мультиплексировать запросы: несколько потоков идут по одному соединению, как по одной широкой трубе. gRPC также переиспользует канал и сжимает заголовки. В руководстве по производительности gRPC прямо рекомендуют переиспользовать стабы и каналы.
Для статьи мы сделали локальный замер одного вызова. Стенд: Linux 6.18.44, 5 vCPU AMD EPYC 9V74, Python 3.13.5; grpcio 1.80.0, protobuf 6.33.6, FastAPI 0.128.2, Uvicorn 0.48.0, httpx 0.28.1. Оба сервиса работали на 127.0.0.1 без TLS: REST — через одно постоянное HTTP-соединение, gRPC — через один канал.
Замерялся не короткий пример выше: User содержал id, name, email, bio на 820 символов, active и score — 867 байт protobuf и 913 байт JSON. После 500 прогревочных запросов шли 10 000 последовательных вызовов одним клиентом, поэтому параллельное мультиплексирование тест не измерял.
В трёх прогонах медиана gRPC была 0,33–0,35 мс, REST — 0,59–0,62 мс; пропускная способность — 2,65–2,93 против 1,59–1,65 тысячи запросов в секунду. Это результат конкретного стека. По медиане вышло примерно в 1,7–1,8 раза, а не в десять.
Выигрыш съедают редкие запросы, прокси, гейтвеи и работа с базой: десятки миллисекунд в БД перекроют экономию на сериализации. При новом соединении добавляется его установка; про TLS — в материале TLS-протокол.
Стриминг в gRPC и REST
В документации это называется gRPC streaming: потоковая передача встроена в модель вызовов. У gRPC четыре типа вызовов:
- Унарный вызов — один запрос и один ответ, например получение профиля.
- Серверный поток — один запрос и много ответов: например, выдача длинного списка порциями.
- Клиентский поток — много сообщений от клиента и один ответ: например, загрузка файла кусками.
- Двунаправленный поток — обе стороны отправляют сообщения независимо, например обмениваются телеметрией в реальном времени.
REST закрывает те же задачи иначе: Server-Sent Events передаёт поток от сервера, WebSocket даёт двусторонний обмен, длинные опросы — редкие обновления. Файлы можно загружать частями по HTTP.
Это не делает REST непотоковым: если поток — часть контракта, gRPC описывает его в .proto; для одного браузерного канала WebSocket или SSE могут быть проще.
Что происходит с gRPC в браузере
Обычный gRPC неудобно вызывать из браузерного JavaScript из-за трейлеров: финальный статус RPC приходит после тела ответа, а браузерные API не дают приложению читать такие HTTP-трейлеры так, как ожидает gRPC.
Поэтому появился gRPC-Web. Между браузером и сервисом обычно ставят Envoy — прокси, который переводит gRPC-Web в gRPC. Трейлеры он кладёт в тело ответа; у фрейма остаётся пятибайтовый префикс: байт флагов и четыре байта длины. В обычном gRPC финальный статус приходит отдельно — как чек после покупки. Браузер не умеет читать такие HTTP-трейлеры, поэтому gRPC-Web переносит статус внутрь тела ответа.
Ошибка RPC может приехать с HTTP 200, поэтому обычный мониторинг увидит успех. В DevTools бинарные данные требуют понимания фреймов. grpc-web поддерживает унарные и серверные потоки, но не клиентский и двунаправленный стриминг. Ограничения разбирает Buf.
Connect сохраняет protobuf-контракт, но для унарных вызовов использует обычные HTTP-коды и работает из браузера без переводящего прокси. Поэтому фронтовый API часто оставляют на REST или Connect, а gRPC — внутри.
Полезный блок со скидкой
По промокоду: KOD (можно просто нажать) — вы получите скидку на все курсы Практикума.
Если хочется проектировать сервисы, которые общаются между собой по gRPC и REST, посмотрите курс Микросервисная архитектура: расширенная версия. Если пока не хватает базы бэкенда, начните с курса Python-разработчик.
Бесплатные вводные курсы в Практикуме тоже есть — например, Основы работы с базами данных и SQL.
Как отлаживать gRPC и REST
REST проверяют curl, Postman и Swagger, а JSON читается глазами. Подробнее — Что такое Swagger и Как тестируют API.
grpcurl и серверная рефлексия
Для gRPC есть grpcurl. При серверной рефлексии — служебном API со схемой сервиса — достаточно адреса и имени метода. Официальная документация gRPC прямо называет grpcurl и Postman инструментами, которые используют рефлексию для отладки.
# Вызываем локальный сервер без TLS и передаём аргумент метода.
grpcurl -plaintext -d '{"id": 42}' localhost:50051 users.v1.UserService/GetUser
Пример ответа:
{
"id": 42,
"name": "Ada Lovelace",
"email": "ada@example.com"
}
Без рефлексии grpcurl нужен .proto или descriptor set — скомпилированное описание схемы. Бинарный лог без схемы не прочитаешь, поэтому нужны трассировка и структурированные логи.
Контракт и версионирование API
В REST контракт обычно фиксируют OpenAPI рядом с кодом. В gRPC исходным контрактом становится .proto. Версионирование API нужно обоим: несовместимое изменение может сломать старый клиент.
У protobuf есть строгие правила обратной совместимости. Номер опубликованного поля менять нельзя: он идентифицирует поле на проводе. Удалённый номер помечают reserved. Новое поле старый клиент просто не знает и пропускает.
Правильно:
protobuf
// Выбираем синтаксис proto3.
syntax = "proto3";
// Описываем обновлённое сообщение.
message User {
// Остальные опубликованные поля остаются без изменений.
int32 id = 1;
string name = 2;
// Запрещаем повторно использовать удалённый номер email.
reserved 3;
// Добавляем новое поле под новым номером.
string phone = 4;
}
Если в опубликованной версии email уже имел номер 3, так делать нельзя:
protobuf
// Выбираем синтаксис proto3.
syntax = "proto3";
// Показываем несовместимое изменение.
message User {
// Нельзя переносить опубликованное поле на другой номер.
string email = 7;
}
REST тоже можно сломать: если строковое поле внезапно стало объектом, старый клиент может не разобрать ответ. Несовместимые изменения обычно выносят в новую версию пути, например /v2/users, или выбирают версию через заголовок.
Когда использовать gRPC, а когда REST
Когда использовать gRPC, решают по потребителю и трафику. Контекст есть в материалах Что такое микросервисы и Микросервисы или монолит: когда что выбирать.
| Сценарий | Выбор | Обоснование |
| Частые вызовы между внутренними сервисами | gRPC чаще | Один долгоживущий канал, protobuf и генерируемый контракт |
| Публичный API для внешних разработчиков | REST или REST-gateway | Обычные HTTP-инструменты и OpenAPI снижают порог интеграции |
| Запросы из браузерного фронтенда | REST или Connect | Не нужен перевод gRPC-Web через отдельный прокси |
| Мобильный клиент на плохой связи | gRPC, если обе стороны под вашим контролем | Компактный protobuf полезен; иначе REST проще диагностировать обычными HTTP-инструментами |
| Подрядчик без опыта protobuf | REST или gateway | Не нужно внедрять .proto, генераторы и новый цикл сборки у партнёра |
| Телеметрия потоком | gRPC чаще | Двунаправленный поток описывается прямо в контракте |
| Редкие фоновые интеграции и вебхуки | REST чаще | Преимущества постоянного gRPC-канала почти не используются |
Публичный REST API можно поднять по инструкции Создаём API на FastAPI. Для контролируемых клиентов и частых внутренних вызовов естественнее бывает gRPC. Если задержка критична, замеряйте свою полезную нагрузку, сеть, прокси и базу.
Как совмещать gRPC gateway и REST
Частая схема — gRPC внутри и REST наружу. gRPC-Gateway читает .proto и генерирует обратный прокси: он принимает HTTP/JSON и перенаправляет запрос во внутренний gRPC-сервис. Из того же контракта можно получить OpenAPI.
Связка сохраняет типизированный внутренний контракт и привычный внешний API. Цена — лишний сетевой переход, преобразование JSON/protobuf и ещё один компонент. Схема оправдана, когда gRPC нужен внутри, а снаружи требуется обычный HTTP API.
Ошибки при переходе на gRPC
- Переезд ради чужого бенчмарка. Сервис может по-прежнему ждать базу, а задержка почти не изменится. Сначала измерьте свой сценарий.
- gRPC наружу без учёта клиентов. Внешним потребителям нужны protobuf-инструменты, браузеру — веб-слой. Проверьте аудиторию и при необходимости оставьте gateway.
- Перенумерация полей после релиза. Так ломается совместимость бинарных сообщений. Номера не переиспользуют, удалённые помечают reserved.
- Вызовы без дедлайна. Дедлайн вызова — крайний срок, после которого RPC отменяется. Без него зависший клиент может держать вызов дольше, чем нужно.
- Расчёт на HTTP-кеш. CDN не кеширует обычный gRPC-вызов как GET. Если кеширование — часть API, нужен отдельный кеш приложения или HTTP-граница.
Частые вопросы
Заменит ли gRPC REST полностью?
Нет. gRPC удобен для типизированных RPC и потоков между контролируемыми клиентами, REST — для браузеров, публичных API и стандартных HTTP-инструментов.
Работает ли gRPC поверх HTTP/3?
Поддержка зависит от стека. Базовый gRPC ориентирован на HTTP/2. В разборе gRPC поверх HTTP/3 трейлеры были одним из блокеров; в quic-go их добавили в версии 0.47.0. Но поддержка всё ещё различается между библиотеками, поэтому проверяйте конкретные клиент и сервер.
Нужен ли protobuf, если нравится JSON?
Protobuf — стандартный формат gRPC, хотя сама модель допускает другие сериализаторы. Если важны человекочитаемый JSON и обычные веб-инструменты, REST или Connect могут быть проще.
Можно ли отдавать gRPC прямо в мобильное приложение?
Да. Нативные приложения могут использовать gRPC SDK напрямую. Но заранее проверьте поддержку платформы, размер библиотеки и поведение на нестабильной сети.
Что выбрать для пет-проекта?
Для небольшого CRUD API с браузером REST обычно требует меньше инфраструктуры. Если цель проекта — изучить protobuf, кодогенерацию и потоковые RPC, gRPC даст больше материала.
Что выбрать в итоге
Сведите выбор к двум вопросам: кто потребляет API и насколько часто идут запросы. Для браузера и внешних интеграций важнее совместимость с обычным HTTP; для частых внутренних вызовов и потоков — строгий контракт и особенности gRPC.
Поэтому спор gRPC против REST не решается одной цифрой из бенчмарка. Смотрите, кто вызывает API, по какой сети клиент обращается к сервису и какая нагрузка ожидается. Под эти условия и выбирайте подход.
Советуем дальше почитать
Клиент-серверная архитектура — что это, каковы принципы работы и примеры — модель «клиент — сервер», сравнение с P2P и serverless, плюсы и минусы. Основа, на которой строятся оба протокола из статьи.
Как тестируют бэкенд — направления тестирования бэкенда: API, нагрузочное, базы данных и инструменты вроде Swagger, Postman и JMeter. Продолжает тему отладки и замеров.
Роадмап Golang 2026: пошаговый план с нуля до первого оффера — путь через основы Go, конкурентность, бэкенд и тестирование. Для тех, кто решил попробовать gRPC на Go.
Что такое Site Reliability Engineering — что такое SRE, SLI, SLO, SLA и мониторинг. Про то, как следить за сервисами после того, как протокол выбран.
7 книг для бэкенд-разработчика про алгоритмы, SQL и архитектуру — книги про микросервисы, работу с данными и надёжность систем. Для тех, кто хочет разобраться в теме глубже одной статьи.
Бонус для читателей
Если вам интересно погрузиться в мир IT и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой или безлимитом на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая.
