3/7. Как я исследовал стоимость банковского BFF GQL vs REST
Как контракт превратил GraphQL из медленного runtime в быстрый API
В предыдущей части GraphQL baseline проиграл REST почти в 3 раза.
Это было неприятно, но полезно: стало ясно, где именно лежит стоимость.
Дальше я сделал shift:
GraphQL — не runtime для произвольных запросов.
GraphQL — язык описания клиентской операции.
Runtime-поверхность — это контракт.
Как это работает:
1. Фронтенд описывает операцию. 2. Build-time tooling — инструменты времени сборки — считает sha256-хеш исходной строки запроса. 3. Генерируется manifest allowlist — белый список разрешенных операций. 4. Генерируется OpenAPI — машиночитаемое описание HTTP API. 5. Операция публикуется как immutable artifact — неизменяемый артефакт версии.
На BFF, то есть Backend for Frontend, при старте строится простая таблица:
`version + hash -> operation handler`
И на горячем read-heavy сценарии — сценарии чтения с высокой нагрузкой — запрос больше не идет в полный `graphql.execute`.
Он идет в fast path — быстрый путь обработки:
- O(1) lookup, то есть быстрый поиск по ключу; - typed handler, то есть заранее известный обработчик; - slim response — облегченный ответ; - меньше allocations — выделений памяти; - меньше сериализации; - меньше лишних полей.
Это уже не "GraphQL против REST".
Это contract-first client-shaped API — контрактный API, сформированный под реальные потребности клиента, против unoptimized enriched REST — неоптимизированного REST с обогащенным ответом.
И тут цифры поменялись.
В прототипе:
- REST BFF: около 15.4k rps, запросов в секунду, на один pod; - contract-first GraphQL BFF: около 21.7k rps; - в cluster x4, то есть кластере из 4 процессов: 54.2k rps против 80.1k rps; - CPU, процессорное время, на 1000 запросов: минус примерно 22%; - network egress, исходящий сетевой трафик: минус примерно 57%; - client VDOM reconcile, сверка виртуального DOM на клиенте: минус примерно 91%.
Главное: выигрыш появился не от модного слова GraphQL.
Он появился от дисциплины:
- persisted operations — заранее сохраненные операции; - manifest allowlist — белый список; - hash-routes — маршруты с хешем; - отключенная introspection — самоописание схемы; - fast path — быстрый путь; - минимальный payload — полезная нагрузка ответа; - строгий publish gate — проверка перед публикацией.
После этого стало понятно: одного BFF мало.
Если контракт становится источником денег и рисков, им нужно управлять как продуктом.
Так появился contract manager.
В следующем посте покажу, зачем менеджеру контрактов админка, политики безопасности, сравнение версий и live sync деплоя.
· 17.07
Хороший разворот: GraphQL начинает выигрывать, когда перестает быть универсальным runtime и становится контрактом. На backend это почти всегда история про O(1) lookup, меньше сериализации и понятный allowlist. Любопытно, как у вас решена эволюция контрактов без слома клиентов?
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
коммент удалён
· 17.07
Контакты версионипованы и храняться на сервере контрактного менеджера списком под каждый проект в менеджере своя история эволюции. Ну и плюс менеджер пинает сервера. Если с обоих сторон контракт реализован. Светит галочку. Даже если на бфф загрушки.
Если Бфф бомбят несколько клиентов, то та же история. Если версия контракта обновилась, то либо обратная совместимость учитывается(+ Тэги в менеджере, с какой версией новый контракт обратно совместим), либо отдельный стенд под новую версию.
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
ответ удалён