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 деплоя.