GraphQL удобен тем, что клиент сам выбирает структуру ответа. Но если не ограничить глубину, сложность и размер выборки, один запрос может перегрузить базу и backend.

Сначала нужно найти самые тяжелые запросы, измерить их сложность и понять, какие поля позволяют уходить в большую вложенность или выгружать слишком много объектов.

Коротко: что делать

  • Собрать примеры тяжелых GraphQL-запросов
  • Проверить глубину вложенности и количество возвращаемых объектов
  • Проверить пагинацию на списках
  • Проверить N+1 в resolvers
  • Посмотреть, есть ли rate limit и auth checks

Основные причины

У этой проблемы редко бывает одна универсальная причина. Обычно нужно проверить связку настроек, данных, кода и внешних сервисов, а потом уже выбирать способ исправления.

  • Нет depth limit и complexity limit
  • Списки можно запрашивать без limit/first
  • Resolvers создают N+1 запросы к базе
  • Дорогие поля доступны любому клиенту
  • Нет таймаута, rate limit или persisted queries

Пошаговая диагностика

Диагностику лучше вести от конкретного примера: один пользователь, один запрос, один документ, одно событие или один экран. Так проще увидеть точку, где система начинает вести себя неправильно.

  • Включить логирование query, duration и user id
  • Проверить explain/profiler для медленных resolvers
  • Посчитать глубину и сложность проблемного запроса
  • Проверить поля, которые возвращают большие списки
  • Проверить повторяемость нагрузки на тестовой базе

Как исправить проблему

Исправление должно закрывать корневую причину, а не только внешний симптом. Если проблема связана с доступами, платежами, данными или безопасностью, сначала стоит сделать резервную копию и проверить правку на тестовом сценарии.

  • Добавить depth limit и query complexity limit
  • Сделать обязательную пагинацию для списков
  • Оптимизировать resolvers через DataLoader и batch-запросы
  • Закрыть дорогие поля правами или отдельными endpoint
  • Добавить таймауты, rate limit и мониторинг медленных запросов

Безопасный план решения

Сначала введите лимиты в режиме наблюдения, чтобы увидеть, какие реальные запросы будут заблокированы. Потом ужесточайте правила и обновляйте клиентов.

Чего не стоит делать

  • Не отключать introspection как единственную защиту
  • Не позволять спискам возвращать все записи
  • Не кешировать персональные данные без учета прав
  • Не вводить лимит так резко, чтобы сломать рабочих клиентов

Что подготовить перед исправлением

  • Схема GraphQL
  • Примеры тяжелых запросов
  • Логи времени выполнения
  • Код resolvers или доступ к backend

FAQ

Почему REST не падал, а GraphQL падает?

GraphQL дает клиенту больше свободы. Без лимитов клиент может собрать очень тяжелый запрос.

Что важнее: depth или complexity?

Оба ограничения полезны. Depth ограничивает вложенность, complexity учитывает дорогие поля и размеры списков.

Нужна ли пагинация в GraphQL?

Да. Любой список должен иметь понятный лимит и способ постраничной загрузки.

Когда стоит обратиться за помощью

Обратиться стоит, если GraphQL API уже тормозит, падает под нагрузкой или доступен внешним клиентам.

Итог

Начните с логирования тяжелых запросов и обязательной пагинации. Если нужно ограничить GraphQL безопасно и без поломки клиентов, можно написать в Telegram @rabotator_support.