Налаштування REST API / GraphQL API Strapi
Strapi автоматично генерує REST API та GraphQL для всіх типів контенту. REST доступний одразу, GraphQL вимагає окремого плагіну. Обидва використовують одну систему прав доступу.
REST API: структура запитів
Формат ответа Strapi v4/v5:
{
"data": {
"id": 1,
"attributes": { "title": "Article", "slug": "article", "publishedAt": "..." }
},
"meta": {}
}
Фільтрація:
# Простий фільтр
GET /api/articles?filters[status][$eq]=published
# Декілька умов (AND)
GET /api/articles?filters[price][$gte]=100&filters[price][$lte]=500
# OR фільтр
GET /api/articles?filters[$or][0][title][$containsi]=react&filters[$or][1][content][$containsi]=react
# Оператори: $eq, $ne, $lt, $lte, $gt, $gte, $in, $notIn, $contains, $containsi, $startsWith, $endsWith, $null, $notNull
Populate (зв'язки та компоненти):
# Заповнити всі зв'язки (1 рівень)
GET /api/articles?populate=*
# Конкретні поля
GET /api/articles?populate[author][fields][0]=name&populate[author][fields][1]=email
# Глибокий populate
GET /api/articles?populate[category][populate][icon]=true
# Динамічні зони
GET /api/pages?populate[sections][populate]=*
Пагінація, сортування, поля:
# Пагінація за сторінками
GET /api/articles?pagination[page]=2&pagination[pageSize]=10
# Пагінація за курсором (для нескінченного скролу)
GET /api/articles?pagination[start]=20&pagination[limit]=10
# Сортування
GET /api/articles?sort[0]=publishedAt:desc&sort[1]=title:asc
# Лише потрібні поля
GET /api/articles?fields[0]=title&fields[1]=slug&fields[2]=excerpt
GraphQL
npm install @strapi/plugin-graphql
// config/plugins.js
module.exports = {
graphql: {
config: {
endpoint: '/graphql',
playgroundAlways: false, // false в production
defaultLimit: 10,
maxLimit: 100,
apolloServer: {
introspection: process.env.NODE_ENV !== 'production',
},
},
},
}
Playground: http://localhost:1337/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 formats }
}
}
category {
data {
attributes { name slug }
}
}
}
}
meta {
pagination { total pageCount }
}
}
}
# Одна стаття
query GetArticle($slug: String!) {
articles(filters: { slug: { eq: $slug } }) {
data {
id
attributes {
title content publishedAt
author {
data { attributes { name bio avatar { data { attributes { url } } } } }
}
}
}
}
}
# Мутації (з аутентифікацією)
mutation CreateComment($articleId: ID!, $text: String!) {
createComment(data: { article: $articleId, text: $text }) {
data {
id
attributes { text createdAt }
}
}
}
Кастомізація GraphQL
// 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
// Обмежити maxPopulateDepth
// config/middlewares.js
{
name: 'strapi::populate-depth',
config: { maxDepth: 3 }
}
// Кешувати важкі запити з Redis
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))
Графік
Налаштування плагіну GraphQL, кастомних резолверів та оптимізація запитів — 2–3 дні.







