Skip to main content

Подключение http клиентов в сервис Ensi

Микросервисная архитектура подразумевает обмен сообщениями между сервисами. Основным способом общения сервисов Ensi между собой являются http вызовы, поэтому http клиент является очень важной частью сервиса и имеет некоторые настройки, о которых необходимо знать.

Конфигурирование http клиента (GuzzleHttp) происходит в файле app/Providers/OpenApiClientsServiceProvider.php.

Глобальные настройки http клиента

В методе configureHandler происходит следующее:

$stack = new HandlerStack(Utils::chooseHandler());

$stack->push(Middleware::httpErrors(new BodySummarizer()), 'http_errors');
$stack->push(Middleware::redirect(), 'allow_redirects');
$stack->push(Middleware::prepareBody(), 'prepare_body');
if (!config('ganesha.disable_middleware', false)) {
$stack->push($this->configureGaneshaMiddleware());
}

$stack->push(new PropagateInitialEventLaravelGuzzleMiddleware());

Т.е. на т.н. GuzzleHandler навешиваются middleware:

  • httpErrors смотрит на код ответа и кидает исключение для 4 и 5 кодов
  • redirect обеспечивает поддержку редиректов
  • prepareBody добавляет в запрос стандартные заголовки вроде Content-Type и Content-Length
  • GaneshaMiddleware - Circuit breaker
  • PropagateInitialEventLaravelGuzzleMiddleware добавляет в запрос заголовок трассировки, содержащий информацию о том кто и где инициировал этот запрос

Дополнительно здесь можно добавить логирование исходящих запросов добаввив GuzzleHttp\Middleware::log().

Регистрация http клиентов к сервисам ensi

После подключения пакет клиента необходимо добавить всего два кусочка кода.

Первый - регистрация клиента в DI контейнере:

$this->registerService(
handler: $handler,
domain: 'catalog',
serviceName: 'offers',
configurationClassName: OffersClientProvider::$configuration,
apisClassNames: OffersClientProvider::$apis
);

Здесь handler - это вышеописанный GuzzleHandler, к которому уже применены глобальные настройки. domain - это не dns домен, а бизнес-домен, по сути просто первая часть имени внешнего сервиса. serviceName - код сервиса клиент к которому мы регистрируем, т.е. вторая часть имени сервиса. Класс OffersClientProvider всегда есть в сгенерированных клиентах, он называется по разному в разных клиентах.

Второй - регистрация переменных конфигурации в файле config/openapi-clients.php:

return [
'catalog' => [
'offers' => [
'base_uri' => env('CATALOG_OFFERS_SERVICE_HOST') . "/api/v1",
],
],
];

Здесь catalog и offers - это вышеописанные domain и serviceName. base_uri содержит адрес сервиса, а точнее берёт его из env переменной CATALOG_OFFERS_SERVICE_HOST. В эту переменную следует передавать адрес с указанием схемы:

CATALOG_OFFERS_SERVICE_HOST=https://master-offers.ensi-dev.greensight.ru

Регистрация http клиентов к внешним сервисам

Если клиент к внешнему сервису (не к сервису ensi) совместим с guzzle, или если вы планируете использовать GuzzleHttp\Client напрямую, то вы можете задать его настройки здесь же - в app/Providers/OpenApiClientsServiceProvider.php. Для этого вы должны сказать DI контейнеру, чтобы в определённой ситуации он отдавал новый GuzzleHttp\Client с тем же самым GuzzleHandler и со специфичными настройками.

$this->app->when(MyHttpClient::class)
->needs(GuzzleHttp\ClientInterface::class)
->give(fn () => new GuzzleHttp\Client([
'handler' => $handler,
'base_uri' => $baseUri,
// other client options
]));