Подключение 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
]));