Bitrix\Main\Web\HttpClient — штатный класс D7 для запросов
к внешним API: интеграции с CRM, платёжными системами, службами
доставки. Разберём базовое использование, обработку ошибок
и настройку таймаутов, без которых внешний запрос может подвесить
весь сайт.
Базовый GET-запрос
<?php
use Bitrix\Main\Web\HttpClient;
$httpClient = new HttpClient();
$response = $httpClient->get('https://api.example.com/status');
if ($httpClient->getStatus() === 200) {
echo $response;
} else {
echo 'Ошибка: ' . $httpClient->getStatus();
}
POST-запрос с JSON-телом
<?php
use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Json;
$httpClient = new HttpClient();
$httpClient->setHeader('Content-Type', 'application/json');
$response = $httpClient->post(
'https://api.example.com/orders',
Json::encode(['order_id' => $orderId, 'status' => 'paid'])
);
$data = Json::decode($response);
Нужна помощь с Битрикс?
Обязательная настройка таймаутов
<?php
$httpClient = new HttpClient();
$httpClient->setTimeout(5); // ожидание ответа целиком
$httpClient->setConnectTimeout(2); // ожидание установки соединения
$response = $httpClient->get('https://api.example.com/status');
Без явного таймаута класс использует значения по умолчанию, которые могут быть неожиданно большими. Если внешний сервис зависает или недоступен, а запрос выполняется синхронно в момент отображения страницы пользователю, весь ответ сайта посетителю встаёт на то же время, пока не истечёт таймаут, — на популярных страницах это быстро превращается в перегрузку сервера очередью зависших PHP-процессов.
Обработка сетевых ошибок
<?php
$httpClient = new HttpClient();
$httpClient->setTimeout(5);
$response = $httpClient->get('https://api.example.com/status');
if ($response === false) {
foreach ($httpClient->getError() as $code => $message) {
AddMessage2Log("HTTP error {$code}: {$message}", 'integration');
}
return null;
}
if ($httpClient->getStatus() >= 400) {
AddMessage2Log('HTTP status ' . $httpClient->getStatus(), 'integration');
return null;
}
get()/post() возвращают false
при сетевой ошибке (недоступен хост, обрыв соединения) — это
отдельная ситуация от HTTP-ошибки со статусом 4xx/5xx, когда сервер
ответил, но с кодом ошибки. Оба случая стоит обрабатывать явно,
а не полагаться только на проверку статуса.
Заголовки авторизации
<?php
$httpClient = new HttpClient();
$httpClient->setHeader('Authorization', 'Bearer ' . $apiToken);
$httpClient->setHeader('Content-Type', 'application/json');
$response = $httpClient->post($apiUrl, $jsonBody);
Почему не стоит вызывать внешний API синхронно на выводе страницы
Если данные от внешнего сервиса нужны на публичной странице (не
в фоновой обработке заказа), прямой синхронный вызов
HttpClient в момент рендера — рискованный подход:
замедление или недоступность стороннего API напрямую замедляет
или ломает страницу сайта. Более устойчивый вариант — кешировать
результат внешнего запроса на разумный срок и обновлять его агентом
в фоне, а не дёргать API при каждом визите пользователя.
<?php
use Bitrix\Main\Data\Cache;
$cache = Cache::createInstance();
if ($cache->initCache(600, 'external_rates', '/external/')) {
$rates = $cache->getVars();
} elseif ($cache->startDataCache()) {
$httpClient = new HttpClient();
$httpClient->setTimeout(3);
$response = $httpClient->get('https://api.example.com/rates');
$rates = $response !== false ? Json::decode($response) : [];
$cache->endDataCache($rates);
}
Частые ошибки
- Таймауты не заданы явно. Зависший внешний сервис держит PHP-процесс дольше, чем допустимо для страницы сайта.
- Не различаются сетевая ошибка и HTTP-статус ошибки. Код проверяет только одно из двух условий и пропускает часть сбоев.
- Синхронный вызов внешнего API на публичной странице без кеша. Недоступность стороннего сервиса напрямую роняет доступность своей страницы.
Итог
HttpClient закрывает большинство сценариев работы
с внешними API, но требует явной настройки таймаутов и раздельной
обработки сетевых ошибок и ошибок HTTP-статуса. Для данных, влияющих
на публичные страницы, безопаснее не вызывать внешний сервис
синхронно на каждый визит, а кешировать результат и обновлять его
фоновым агентом.
