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.