Дружим gRPC с долгоживущим проектом, PHP и фронтендом



ару лет назад мы достаточно спокойно работали нашей небольшой командой и делали хостинг. Вышло так, что каждый сервис в системе обладал собственным уникальным и неповторимым API. Но потом это стало проблемой и было решено все переделать.

Мы расскажем о том, как объединить внешнее API с внутренним и что делать, если у вас много кода на PHP, но хочется воспользоваться преимуществами gRPC.

Сейчас очень много говорят про микросервисы и SOA в целом. Наша инфраструктура не исключение: ведь мы занимаемся хостингом и наши сервисы позволяют управлять почти тысячей серверов.

Со временем сервисов в нашей системе стало появляться все больше: стали регистратором доменов — выносим регистрацию в отдельный сервис; метрик с серверов стало очень много — пишем сервис, который делает выборки из ClickHouse / InfluxDB; Нужно сделать эмулятор запуска задач «как через Crontab»; для пользователей — пишем сервис. Наверное, это многим будет знакомо.

Входящих задач в разработке много. Количество различных сервисов растет плавно и, вроде бы, незаметно. Заранее учесть все будущие нюансы невозможно, поэтому на смену одним API приходили другие, более лучшие. Но настал день, когда стало очевидно, что у нас развелось слишком много протоколов:


Чем больше становилось сервисов и связей между ними, тем дольше и сложнее было решать задачи: требовалось изучить несколько разных API, написать к ним клиенты и только потом приступить к реальной работе.

Ах, да… еще ведь документация нужна. Иначе в чатиках происходят такие диалоги:
— Ребят, как мне получить баланс пользователя из биллинга?
— Сделай вызов в billing/getBalance(customerId)
— А список услуг как получить?
— Не помню, поищи нужный контроллер в
Короче говоря, зародилась мечта о волшебном едином стандарте и технологии для создания сетевых API, которые решат все проблемы и сэкономят нам вагон времени.

Формируем требования
Немного подумав, мы составили свой небольшой список требований:
  • Используемый способ описания API должен быть декларативным
  • Результат должен быть однозначным и человеко-понятным: нужно проводить code review
  • Нужна возможность описывать как успешный flow, так и ошибки. Причем это должно делаться явно для каждого метода
  • На основе описания нужно генерировать как можно больше скучного кода для клиента и сервера

Из коробки он удовлетворял почти всем нашим требованиям. Если в двух словах:
  • Декларативное описание методов и структур данных
  • Он очень читабельный и простой. По получившимся .proto-файлам легко проводить code review. Синтаксис IDL близок к популярным ЯП
  • Завезены генераторы под большинство популярных ЯП (но есть нюанс. О нем ниже)
  • gRPC — просто механизм RPC без каких-либо строгих требований к организации API. Это дает возможность разработать собственные принципы и гайдлайны с учетом накопленного опыта

Однако, идеальных технологий не существует. Для нас возникло несколько камней преткновения:
  • Мы активно используем PHP и он не умеет в сервер gRPC;
  • Наш фронтенд по-прежнему ожидает привычный HTTP. На текущий момент мы были вынуждены «проксировать» запросы фронтенда через отдельное приложение, формирующее правильные запросы к внутреннему API. В подавляющем большинстве случаев это лишняя скучная работа. Хотелось бы внутри нашей системы все отдавать через один протокол с автоматической конвертацией в HTTP для фронтенда.
К счастью, мы достаточно легко решили эти проблемы. Далее я буду предполагать, что читатель знаком с gRPC. Если нет — лучше сначала обратиться к упомянутой выше статье.

И так далее, много технической информации
Надеюсь на Хабре топик не удалится, т.к. сохранять для Истории рынка не вижу смысла, черзе 5 лет устареет все. Просто запомним факт, что была такая новость ;)
habr.com/company/beget/blog/348008/