Более простой способ обновить промежуточное ПО

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

Я объясню, как настроить промежуточное ПО Guzzle для регистрации запросов в файл. Это полезно для отладки и исторических целей.

Способ сделать это — передать новый HandlerStack с нашим промежуточным программным обеспечением ведения журнала в наш экземпляр Client.

Синтаксис создания нового экземпляра Guzzle следующий:

$client = new \GuzzleHttp\Client([
    'base_uri' => "http://www.example.com/api",
    'handler' => $handlerStack,
    ]),
]);

$handlerStack в конечном итоге будет содержать промежуточное программное обеспечение, которое обрабатывает ведение журнала.

Настройка файла журнала

Перед настройкой промежуточного программного обеспечения мне нужно создать экземпляр, который обрабатывает запись наших сообщений журнала в файл. Я буду использовать пакет Monolog, чтобы справиться с этим. Это позволяет легко достичь желаемых критериев наличия файла ежедневного журнала рядом с моим по умолчанию laravel.log.

В моем AppServiceProvider я настрою вспомогательную функцию для создания регистратора:

Настройка промежуточного программного обеспечения

Для промежуточного программного обеспечения Guzzle для ведения журнала требуется регистратор (который я только что создал выше) и экземпляр MessageFormatter, который контролирует то, что регистрируется.

Я настрою вспомогательную функцию для создания промежуточного программного обеспечения:

private function createGuzzleLoggingMiddleware(string $messageFormat)
{
    return \GuzzleHttp\Middleware::log(
        $this->getLogger(),
        new \GuzzleHttp\MessageFormatter($messageFormat)
    );
}

$messageFormat — это строка, которая форматирует сообщения журнала, используя подстановку переменных для запросов, ответов и других транзакционных данных. Возможные замены можно посмотреть здесь — но я придумал несколько удобных:

Запись запроса: {method} {uri} HTTP/{version} {req_body}
Запись ответа: RESPONSE: {code} — {res_body}

Создание стека обработчиков

Теперь, когда у меня есть способ легко обновить экземпляр промежуточного программного обеспечения Guzzle для ведения журналов, я могу создать новый HandlerStack, чтобы добавить промежуточное программное обеспечение в него:

$handlerStack = \GuzzleHttp\HandlerStack::create();
$handlerStack->push(
    $this->createGuzzleLoggingMiddleware($messageFormat)
);

Регистрация запроса и ответа отдельно

Я решил зарегистрировать запрос и ответ в двух отдельных записях журнала. Кажется, что единственный способ добиться этого — отправить несколько промежуточных программ ведения журналов в Guzzle, поэтому я настроил вспомогательную функцию для создания HandlerStack со всеми необходимыми промежуточными программами ведения журналов из массива строк формата сообщений, которые я хотел бы регистрировать.

И вот оно! Теперь добавить несколько регистраторов в наш клиент Guzzle так же просто, как код ниже:

$client = new Client([
    'base_uri' => "http://example.com",
    'handler' => $this->createLoggingHandlerStack([
        '{method} {uri} HTTP/{version} {req_body}',
        'RESPONSE: {code} - {res_body}',
    ]),
]);

Краткое примечание о работе с ответами Guzzle

После настройки логгера я понял, что больше не могу получить доступ к телу ответа — оказывается, это была моя ошибка.

Раньше я обращался к содержимому ответа, используя следующую строку:

$this->client->get($endpoint)->getBody()->getContents();

Но оказывается, что это получает «оставшееся содержимое тела в виде строки» — и, поскольку промежуточное ПО уже получило доступ к телу, чтобы зарегистрировать его, не осталось никакого содержимого для извлечения.

Правильный способ получить доступ к содержимому ответа — преобразовать тело в строку:

(string) $this->client->get($endpoint)->getBody();
Want to Connect?
Follow me on Twitter as I continue to document what I learn on my software-building journey.