#php #guzzle6
#php #guzzle6
Вопрос:
Я использую Guzzle6 в версии PSR7, потому что он хорошо интегрируется с аутентификацией Hawk. Теперь я сталкиваюсь с проблемами добавления тела к запросу.
private function makeApiRequest(Instructor $instructor): ResponseInterface
{
$startDate = (new CarbonImmutable('00:00:00'))->toIso8601ZuluString();
$endDate = (new CarbonImmutable('00:00:00'))->addMonths(6)->toIso8601ZuluString();
$instructorEmail = $instructor->getEmail();
$body = [
'skip' => 0,
'limit' => 0,
'filter' => [
'assignedTo:user._id' => ['email' => $instructorEmail],
'start' => ['$gte' => $startDate],
'end' => ['$lte' => $endDate],
],
'relations' => ['reasonId']
];
$request = $this->messageFactory->createRequest(
'POST',
'https://app.absence.io/api/v2/absences',
[
'content_type' => 'application/json'
],
json_encode($body)
);
$authentication = new HawkAuthentication();
$request = $authentication->authenticate($request);
return $this->client->sendRequest($request);
}
Когда я var_dump
ввожу $request
переменную, я не вижу тела внутри запроса. Это подтверждается тем фактом, что API отвечает так, как будто тело не было отправлено. Я перепроверил это в Postman. Как вы можете видеть, в теле указаны фильтры и разбивка на страницы, поэтому легко заметить, что результаты, которые я получаю, на самом деле не фильтруются.
Тот же запрос в Postman (с телом) работает безупречно.
Поскольку параметр может иметь тип StreamInterface
, вместо этого я создал поток и передал ему тело. Тоже не сработало.
Комментарии:
1. Действительно, не рекомендовал бы писать свой собственный JSON. Создайте массив и используйте
json_encode()
вместо2. Да, у меня было предчувствие, что ты делаешь это не так. Спасибо за комментарий. Теперь заменено на array.
3. Все еще не работает, верно: (
4. Нет… К сожалению, нет. Пробовал это и раньше. Копаясь в реализации Guzzle, я, кажется, не могу понять, что делает stream_for(). А также не причина, по которой в RequestInterface отсутствует какой-либо метод, связанный с телом или содержимым…
Ответ №1:
Простые JSON
запросы могут быть созданы без использования json_encode()
… смотрите документацию.
use GuzzleHttpClient;
$client = new Client([
'base_uri' => 'https://app.absence.io/api/v2',
'timeout' => 2.0
]);
$response = $client->request('POST', '/absences', ['json' => $body]);
Комментарии:
1. Я использую вариант PSR7, потому что он позволяет легко интегрировать аутентификацию Hawk. Ваше предложение вынудило бы меня использовать систему событий Guzzle для обогащения запроса заголовком аутентификации.
2. @Chrisissorry существует несколько способов создания запросов, поэтому я добавил термин «простой». Сначала не заметил неверный
content_type
заголовок, но это может быть интерпретировано не как данные формы, а, скорее всего, какtext/plain
(такие нераспознанные заголовки, скорее всего, будут проигнорированы).
Ответ №2:
Обнаружена проблема, на самом деле мое тело POST НЕ пустое. Просто оказывается, что сброс Request
ничего не намекает на фактическое тело, вложенное в сообщение.
Я могу порекомендовать всем, у кого есть подобные проблемы, использоватьhttp://httpbin.org/#/HTTP_Methods/post_post для отладки тела POST.
Наконец, проблема заключалась в том, что мое content_type
написание заголовка было неправильным, поскольку сервер ожидает заголовок Content-Type
. Из-за этого данные JSON были отправлены как данные формы.