Запросы к другим сервисам
Курс валют, оплата, доставка, вход через соцсеть — сайт постоянно обращается к чужим API. В Symfony для этого есть компонент HttpClient: он отправляет запросы и разбирает ответы.
Запрос GET
use Symfony\Contracts\HttpClient\HttpClientInterface;
#[Route('/rates', name: 'rates')]
public function rates(HttpClientInterface $client): Response
{
$response = $client->request('GET', 'https://api.example.com/rates');
$data = $response->toArray();
return $this->render('rates.html.twig', ['rates' => $data['rates']]);
}toArray() превращает ответ JSON в массив.
Что можно узнать из ответа
| Метод | Что возвращает |
|---|---|
getStatusCode() | Код состояния |
getHeaders() | Заголовки |
getContent() | Тело ответа строкой |
toArray() | Разобранный JSON |
Параметры адреса
$response = $client->request('GET', 'https://api.example.com/users', [
'query' => ['page' => 2, 'role' => 'admin'],
]);Адрес превратится в /users?page=2&role=admin, значения будут закодированы.
Запрос POST
$response = $client->request('POST', 'https://api.example.com/orders', [
'json' => ['product_id' => 42, 'quantity' => 2],
]);
$order = $response->toArray();Ключ json кодирует данные и добавляет заголовок Content-Type. Для обычной формы используют ключ body.
Заголовки и авторизация
$response = $client->request('GET', 'https://api.example.com/me', [
'auth_bearer' => $token,
'headers' => ['Accept' => 'application/json'],
'timeout' => 5,
]);timeout ограничивает ожидание: без него медленный сервис задержит и вашу страницу.
Ошибки
Если сервис ответил кодом 4xx или 5xx, методы toArray() и getContent() бросают исключение. Сбой сети — тоже исключение:
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
try {
$data = $client->request('GET', $url)->toArray();
} catch (HttpExceptionInterface $e) {
$code = $e->getResponse()->getStatusCode();
// сервис ответил ошибкой
} catch (TransportExceptionInterface $e) {
// сервис недоступен
}Настроенный клиент
Общие параметры одного API задают в настройках:
# config/packages/framework.yaml
framework:
http_client:
scoped_clients:
github.client:
base_uri: 'https://api.github.com'
headers:
Accept: 'application/vnd.github+json'
Authorization: 'Bearer %env(GITHUB_TOKEN)%'Имя аргумента выбирает клиента:
public function __construct(private HttpClientInterface $githubClient) {}
public function repos(string $user): array
{
return $this->githubClient->request('GET', "/users/$user/repos")->toArray();
}Частая ошибка
Запрос отправляется не в момент вызова request(), а когда вы обращаетесь к ответу. Если не вызвать getStatusCode(), getContent() или toArray(), ошибка сервиса останется незамеченной до уничтожения объекта. Всегда читайте ответ и оборачивайте обращение к чужому сервису в try: рано или поздно он окажется недоступен.