Нужно ли заставлять фронтенд работать с gRPC напрямую
Что проверяют
Знаете ли вы, что именно мешает браузеру говорить по gRPC, и умеете ли выбирать границу между внутренними и внешними API. Для бэкендера на Go это ещё и вопрос о том, кто платит за удобный контракт: вы или веб-команда.
Как отвечать
Прямо из браузера обычный gRPC не работает. Дело не в HTTP/2, его браузеры поддерживают, а в том, что JavaScript не управляет фреймами и не читает трейлеры, а именно в трейлере gRPC передаёт статус вызова. Отсюда три рабочих варианта:
gRPC-Webплюс прокси, который переводит его в обычный gRPC: Envoy с соответствующим фильтром или прокси на Go рядом с сервисом;- протокол Connect: один сервер отвечает и на gRPC, и на
gRPC-Web, и на простой POST с JSON, который видно в devtools и можно повторить через curl; - шлюз поверх тех же proto, отдающий привычный REST, если наружу нужен обычный HTTP API.
Аргумент за прямую работу: единый контракт и генерация типов, веб перестаёт писать модели руками и ловить расхождения. Аргументы против: бинарный трафик неудобно отлаживать, кэшировать ответы на CDN не выйдет, все вызовы это POST, а прокси становится ещё одним звеном, которое надо катить и мониторить. Для мобильных клиентов и вызовов между сервисами gRPC напрямую вопросов не вызывает.
Где спотыкаются
Обещают двунаправленный стриминг в браузере. В gRPC-Web доступен серверный стрим, клиентского и двунаправленного нет, и если продукту нужен дуплекс, разговор уходит в WebSocket.
Забывают про публичность API. Proto как контракт для внешних интеграторов тяжелее описания в OpenAPI: партнёру придётся ставить генератор, а не открыть страницу с примерами запросов.
Не проговаривают версионирование. Номер удалённого поля переиспользовать нельзя, для этого есть reserved, а старый клиент обязан игнорировать незнакомые поля, а не падать на них.