gRPC-GoMiddleExperience

В каких проектах gRPC-Go оправдан, а где он становится источником лишней сложности?

gRPC-Go оправдан в высоконагруженных внутренних микросервисах с чётким контрактом API; избыточен для простых CRUD-сервисов, публичных REST API или небольших монолитов без явной необходимости в стриминге.

Когда gRPC-Go оправдан

gRPC-Go хорошо вписывается в следующие сценарии:

  • Внутренние микросервисы с высокой нагрузкой: Protobuf быстрее JSON в 3–10 раз, HTTP/2 снижает задержки при fan-out вызовах. Типичный пример — payment gateway, real-time recommendation engine, ML inference pipeline.
  • Чёткий контракт между командами: .proto-файлы — это живая документация; protoc-gen-go генерирует типизированный клиент, который сложно использовать неправильно.
  • Стриминговые данные: серверный стриминг для live-feeds, двунаправленный — для чатов и телеметрии. Реализовать это поверх REST/JSON значительно сложнее.
  • Полиглотная архитектура: gRPC поддерживает Go, Python, Java, Rust, Node.js из одного .proto; JSON REST API требует отдельной генерации или ручных клиентов.
  • Дедлайны и отмена: механизм propagation контекста и grpc-timeout заголовок работают из коробки — критично для SLA-чувствительных систем.

Когда gRPC-Go создаёт лишнюю сложность

  • Публичный API для браузеров: браузеры не поддерживают gRPC напрямую. Нужен grpc-gateway или connect-go, что добавляет слой. Если клиент только браузер — REST проще.
  • Небольшой монолит или 2–3 сервиса: overhead от code generation, protoc toolchain и необходимости версионировать .proto не окупается при малом числе вызывающих сторон.
  • CRUD без сложной логики: для простого GET /users/{id} gRPC добавляет слой абстракции без выигрыша в производительности при разумной нагрузке.
  • Команда без опыта с Protobuf: кривая обучения включает настройку buf.build или protoc, понимание wire format, управление reserved полями и backward compatibility.

Конкретное сравнение

// REST: любой HTTP-клиент, curl, браузер — без инфраструктуры
resp, _ := http.Get("https://api.example.com/users/42")

// gRPC-Go: нужен сгенерированный клиент, TLS, правильный port
conn, _ := grpc.NewClient("api.example.com:443",
    grpc.WithTransportCredentials(credentials.NewTLS(nil)))
client := pb.NewUserServiceClient(conn)
resp, _ := client.GetUser(ctx, &pb.GetUserRequest{Id: "42"})

REST быстрее в разработке прототипа, gRPC даёт типобезопасность и производительность в production.

Альтернативы при частичных требованиях

  • connect-go (bufbuild) — gRPC-совместимый протокол, но работает через обычный HTTP/1.1+JSON, доступен из браузера без прокси.
  • twirp — Protobuf поверх HTTP/1.1, проще в отладке, но без стриминга.
  • OpenAPI + oapi-codegen — типизированный REST с code gen, знакомый экосистеме.

Подводные камни

  • Добавить gRPC «потому что модно» без реального fan-out или стриминга — команда платит за сложность, не получая выигрыша в latency.
  • Не заложить versioning стратегию с самого начала — смена номеров полей в .proto ломает бинарную совместимость без явного reserved.
  • Использовать gRPC для публичного API без grpc-gateway — браузерные клиенты требуют дополнительного слоя или Envoy с grpc_json_transcoder.
  • Недооценить operational cost: grpcurl, wireshark, логирование payload — всё сложнее, чем с JSON REST.
  • Хранить .proto только в одном репозитории без shared registry (buf BSR) — при нескольких командах возникают конфликты версий.
  • Не настроить health-check через grpc_health_v1 — стандартные load-balancer health-check endpoints не работают с gRPC из коробки.
  • Полагаться на встроенный DNS-балансировщик gRPC без понимания ограничений — при Kubernetes service DNS резолвится в один IP, а не список pod'ов.

What hurts your answer

  • Выбирать gRPC-Go по популярности, а не по требованиям проекта
  • Игнорировать опыт команды, эксплуатацию и стоимость поддержки
  • Не называть ситуации, где gRPC-Go будет плохим выбором

What they're listening for

  • Называет критерии выбора gRPC-Go
  • Учитывает команду, эксплуатацию, стоимость и риски
  • Может назвать сценарии, где выбрал бы альтернативу

Related topics