Проблема: стандартный REST API в 1С-Битрикс на каталоге из 10 000 товаров генерирует 5 000+ запросов для получения вложенных данных (цены, остатки). Клиент мобильного приложения грузит 400 КБ лишних полей. GraphQL решает это за один запрос — клиент сам описывает нужные поля и получает ровно то, что запросил. Мы внедряем GraphQL на Битрикс уже несколько лет; фактическая экономия трафика достигает 60%, а время ответа сокращается с 3 секунд до 200 мс. При объёме в 500 000 запросов в месяц экономия на CDN составляет $20–50.
Почему GraphQL лучше REST для сложных каталогов?
REST-эндпоинт /api/products/123 возвращает фиксированный набор полей. Мобильному приложению нужны имя и цена — оно получает 40 полей. Другому клиенту нужны остатки по складам — он делает второй запрос. GraphQL позволяет каждому клиенту описать свои потребности:
# Мобильное приложение query { product(id: 123) { name price { value currency } images { url } } } # Складской модуль query { product(id: 123) { name sku { id stock { warehouse quantity } } } } Один эндпоинт, один запрос — разные данные для разных клиентов. GraphQL лучше REST в сценариях с несколькими потребителями: фронтенд, мобильное приложение, внешние сервисы — каждый получает только свои данные.
Главная проблема GraphQL — N+1 запросов. Клиент запросил список из 20 товаров, для каждого нужны цены — 20 отдельных запросов к b_catalog_price. Решение: DataLoader (паттерн batching). DataLoader накапливает запросы в рамках одного GraphQL-выполнения и делает один батч-запрос:
class PriceDataLoader { private array $buffer = []; public function load(int $productId): Promise { $this->buffer[] = $productId; return new Promise(fn($resolve) => $resolve($productId)); } public function dispatch(): void { // Один запрос для всех накопленных ID $prices = \Bitrix\Catalog\PriceTable::getList([ 'filter' => ['PRODUCT_ID' => $this->buffer], ])->fetchAll(); // Распределяем результаты } } Вместо 20 запросов — 1. Для вложенных данных (товары → SKU → остатки) экономия кратная. На крупных каталогах (50 000+ товаров) это сокращает время ответа до 200 мс.
Как внедрить GraphQL в Битрикс: от схемы до endpoint?
Битрикс не поддерживает GraphQL из коробки. Реализация строится поверх стандартного PHP Битрикс через библиотеку GraphQL-PHP — это де-факто стандарт для PHP.
Точка входа — один контроллер на URL /api/graphql, который принимает POST-запросы с JSON-телом ({ "query": "...", "variables": {...} }).
// /local/php_interface/api/graphql.php use GraphQL\GraphQL; use GraphQL\Type\Schema; $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); $schema = new Schema([ 'query' => QueryType::build(), 'mutation' => MutationType::build(), ]); $result = GraphQL::executeQuery($schema, $input['query'], null, null, $input['variables'] ?? null); header('Content-Type: application/json'); echo json_encode($result->toArray()); Каждый тип GraphQL соответствует сущности Битрикс. Пример для каталога:
// ProductType ObjectType(['name' => 'Product', 'fields' => fn() => [ 'id' => ['type' => Type::int()], 'name' => ['type' => Type::string()], 'code' => ['type' => Type::string()], 'price' => [ 'type' => PriceType::get(), 'resolve' => fn($product) => PriceResolver::resolve($product['ID']), ], 'sku' => [ 'type' => Type::listOf(SkuType::get()), 'resolve' => fn($product) => SkuResolver::resolve($product['ID']), ], 'sections' => [ 'type' => Type::listOf(SectionType::get()), 'resolve' => fn($product) => SectionResolver::resolve($product['IBLOCK_SECTION_ID']), ], ]]); Резолверы — функции, которые получают данные для каждого поля. Резолвер для price обращается к b_catalog_price, для sku — к дочернему инфоблоку SKU, для sections — к b_iblock_section. Опыт показывает, что правильно спроектированная схема типов окупается на этапе расширения функционала.
Как реализовать мутации и авторизацию?
Мутации в GraphQL — аналог POST/PUT/DELETE в REST:
mutation { createOrder(input: { productId: 123, quantity: 2, deliveryAddress: "Москва, ул. Ленина, 1" }) { orderId status totalAmount } } Резолвер мутации вызывает \Bitrix\Sale\Order::create() с нужными параметрами — стандартное D7 API модуля sale. Мы рекомендуем валидировать входные данные через резолверы и возвращать понятные ошибки.
Авторизация реализуется на двух уровнях. Уровень запроса: middleware проверяет JWT или сессию Битрикс перед выполнением GraphQL-запроса. Уровень поля: конкретное поле доступно только авторизованным пользователям. Например, поле costPrice (себестоимость) видит только пользователь с ролью «Администратор». Реализуется в резолвере без дополнительных code-блоков — простая проверка прав.
Как кешировать GraphQL и организовать подписки?
GraphQL сложнее кешировать, чем REST: запросы уникальны по набору полей и переменных. Подходы:
- Кеш на уровне резолвера — наиболее распространённый: резолвер кеширует результат конкретного DataLoader-батча в Redis/Memcache. TTL зависит от частоты обновления данных.
- Persisted Queries: клиент отправляет хеш заранее зарегистрированного запроса вместо полного текста. Это позволяет кешировать на уровне HTTP (CDN кеширует GET-запросы с хешем).
-
Тегированный кеш Битрикс: регистрируем теги при чтении данных (
iblock_id_1), инвалидируем при изменении.
Для высоконагруженных проектов мы используем комбинацию всех трёх методов — это даёт 90% cache hit rate.
GraphQL поддерживает подписки — realtime обновления через WebSocket. При изменении заказа все подписчики получают уведомление. Для Битрикс реализуется через отдельный WebSocket-сервер (Ratchet/Swoole) + Redis pub/sub. При изменении сущности в Битрикс (через обработчик события) публикуем в Redis-канал, WebSocket-сервер доставляет всем подписчикам.
Что входит в нашу разработку и этапы работ
Мы предоставляем полный комплект: проектирование схемы, реализацию типов и резолверов, настройку DataLoader и кэширования, документацию в формате GraphQL SDL + Markdown, обучение команды работе с GraphiQL, и гарантийную поддержку 30 дней после деплоя. Оценим ваш проект за 1 день. Стоимость проекта — от $2k–5k в зависимости от сложности.
| Этап | Содержание | Срок |
|---|---|---|
| Проектирование схемы | Типы, запросы, мутации, связи | 1 неделя |
| Базовая инфраструктура | GraphQL endpoint, авторизация | 3–5 дней |
| Реализация типов и резолверов | Каталог, заказы, пользователи | 2–4 недели |
| DataLoader (N+1) | Batching для вложенных данных | 1 неделя |
| Кеширование | Redis DataLoader cache + теги | 1 неделя |
| Авторизация полей | Разграничение доступа | 3–5 дней |
| Тестирование | Unit-тесты резолверов, интеграционные тесты | 1 неделя |
Сравнение подходов
| Критерий | REST | GraphQL |
|---|---|---|
| Overfetching/underfetching | Часто | Нет |
| Количество запросов для вложенных данных | N+1 | 1 |
| Гибкость для разных клиентов | Низкая | Высокая |
| Сложность кэширования | Средняя | Высокая |
GraphQL на Битрикс — зрелое решение для проектов с несколькими клиентами и сложными вложенными данными. Для простого сайта с одним фронтендом — REST достаточно. GraphQL Specification (October 2021) подтверждает преимущества. Получите консультацию — наши инженеры оценят ваш проект за 1 день и помогут выбрать оптимальный вариант. Свяжитесь с нами для обсуждения вашего проекта.







