Представьте: фронтенд требует данных с кастомной вложенностью — статьи с авторами, категориями, тегами и динамическими зонами. Без правильной настройки API вы получаете N+1 запросы, гигантские JSON-ответы и падение LCP. Например, типичный запрос на получение статьи с автором и категорией без оптимизации генерирует 4 запроса к БД, что увеличивает TTFB до 2 секунд. После настройки — один запрос и TTFB 200 мс. Мы оптимизировали такие сценарии для 30+ проектов за 6 лет работы. В этом руководстве разберём, как настроить REST и GraphQL в Strapi, избежать типовых ошибок и ускорить API до 10 раз.
Почему стоит использовать REST и GraphQL вместе?
REST API в Strapi работает «из коробки» — идеально для простых списков и стандартных CRUD. GraphQL через плагин подключается за 5 минут и решает проблему overfetching. GraphQL уменьшает объём передаваемых данных до 80% по сравнению с REST при сложных иерархиях — это подтверждает наша практика. Мы комбинируем их: REST для публичных эндпоинтов, GraphQL для админки и внутренних инструментов. Сравнение возможностей — в таблице.
| Критерий | REST API | GraphQL API |
|---|---|---|
| Готовность | Сразу после запуска | Требует установки плагина |
| Запросы | Множество запросов для связей | Один запрос с вложенными объектами |
| Кэширование | HTTP-кеш (ETag, CDN) | Сложнее (требуется persisted queries) |
| Гибкость | Фиксированная структура ответа | Клиент выбирает поля |
| Производительность | Легче оптимизировать через DB | Риск глубокой вложенности и N+1 |
Как настроить REST API?
Формат ответа Strapi единообразен:
{
"data": {
"id": 1,
"attributes": { "title": "Article", "slug": "article", "publishedAt": "..." }
},
"meta": {}
}
Для фильтрации, populate, пагинации и сортировки используйте query-параметры. Пример запроса со всеми возможностями:
GET /api/articles?filters[status][$eq]=published&filters[price][$gte]=100&populate=author,category&sort[0]=publishedAt:desc&pagination[page]=2&pagination[pageSize]=10&fields[0]=title,slug
Поддерживаются операторы: $eq, $ne, $lt, $in, $contains, $startsWith, $endsWith, $null, $notNull и их регистронезависимые варианты с суффиксом i. Для связей используйте populate — он может быть глубоким, но ограничьте глубину через middleware strapi::populate-depth (рекомендуем maxDepth: 3), чтобы избежать N+1.
Как подключить и кастомизировать GraphQL?
Установите плагин @strapi/plugin-graphql и добавьте конфигурацию в config/plugins.js (endpoint, лимиты, отключение playground в production). Пример GraphQL запроса на получение статей с вложенными данными:
query GetArticles($locale: I18NLocaleCode, $page: Int) {
articles(
locale: $locale
pagination: { page: $page, pageSize: 10 }
sort: "publishedAt:desc"
filters: { publishedAt: { notNull: true } }
) {
data {
id
attributes {
title
slug
excerpt
publishedAt
cover { data { attributes { url alternativeText } } }
category { data { attributes { name slug } } }
}
}
meta { pagination { total pageCount } }
}
}
Для кастомных резолверов используйте extensionService. Создайте поле featuredArticles, возвращающее только избранные статьи:
// src/index.ts
export default {
register({ strapi }) {
const extensionService = strapi.plugin('graphql').service('extension')
extensionService.use(({ nexus }) => ({
types: [
nexus.extendType({
type: 'Query',
definition(t) {
t.field('featuredArticles', {
type: 'ArticleEntityResponseCollection',
resolve: async (_root, _args, context) => {
const articles = await strapi.entityService.findMany(
'api::article.article',
{
filters: { featured: true },
populate: ['cover', 'category'],
sort: { publishedAt: 'desc' },
limit: 6,
}
)
return { data: articles }
},
})
},
}),
],
}))
},
}
Как повысить производительность API?
Кэшируйте тяжёлые запросы с Redis. Например, для featured-articles:
const redis = new Redis(process.env.REDIS_URL)
const cachedFeatured = await redis.get('featured-articles')
if (cachedFeatured) return JSON.parse(cachedFeatured)
const articles = await strapi.entityService.findMany(...)
await redis.setex('featured-articles', 300, JSON.stringify(articles))
Типичная ошибка — N+1 запросы при агрессивном populate. Если использовать populate=*, Strapi выполняет отдельные запросы к БД для каждой связи. Ограничение глубины через middleware strapi::populate-depth и кэширование Redis устраняют эту проблему. Хорошо настроенный GraphQL в Strapi работает до 5 раз быстрее REST для сложных запросов с множеством связей.
Дополнительно используйте Varnish или CDN для кэширования ответов публичных эндпоинтов. Сравнение стратегий кэширования — во второй таблице.
| Стратегия | Когда использовать | Выигрыш в скорости |
|---|---|---|
| Redis | Динамические данные, частые обновления | Снижение нагрузки на БД в 5–10 раз |
| Varnish | Публичные, редко меняющиеся эндпоинты | Ускорение ответов до 50 мс |
| CDN | Статические ресурсы (изображения, файлы) | Близость к пользователю, снижение TTFB |
Как оптимизировать Strapi API: пошаговый план
- Анализ текущих запросов. Используйте встроенный логгер Strapi или сторонние инструменты (Kibana) для выявления медленных эндпоинтов.
-
Настройка populate-depth. Установите middleware
strapi::populate-depthсmaxDepth: 3в конфигурации. - Внедрение кэширования Redis. Кэшируйте результаты тяжёлых запросов с TTL 300 секунд — это снижает нагрузку на БД до 10 раз.
- Переход на GraphQL для сложных связей. Если фронтенд запрашивает вложенные данные, используйте GraphQL — он уменьшает объём передаваемых данных до 80%.
- Мониторинг и итерация. Регулярно проверяйте производительность через Strapi audit logs и корректируйте настройки.
Что входит в настройку API под ключ?
- конфигурация REST и/или GraphQL с учётом нагрузки;
- кастомные резолверы и мидлвары;
- оптимизация populate и кэширование (Redis, Varnish);
- настройка прав доступа и ролей;
- документация (Postman-коллекция, описание эндпоинтов);
- обучение команды (1–2 сессии);
- поддержка 2 недели после сдачи.
Сроки
Настройка GraphQL плагина, кастомных резолверов и оптимизация запросов — от 2 до 5 дней. Стоимость рассчитывается индивидуально — пришлите бриф, и мы оценим ваш проект. Правильная настройка кэширования может сократить расходы на серверные мощности до 40%, а средняя экономия бюджета на инфраструктуру заказчиков составляет 30%. Закажите консультацию, чтобы обсудить детали вашего API. Получите консультацию — свяжитесь с нами.
Источник: официальная документация Strapi по GraphQL — https://docs.strapi.io/dev-docs/plugins/graphql







