Кастомні контролери Strapi: перевизначення, валідація, пагінація

Чому стандартних контролерів Strapi недостатньо?

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Кастомні контролери Strapi: перевизначення, валідація, пагінація
Середній
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1467
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1317
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1014
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1276
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1019
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1019

Чому стандартних контролерів Strapi недостатньо?

При розробці на Strapi рано чи пізно впираєшся в обмеження стандартного CRUD. Ми побудували інтернет-магазин з 50 000 товарів — стандартний find видавав відповідь за 2 секунди. Кастомний контролер з пагінацією та фільтрацією знизив час до 300 мс — приріст швидкості в 6.7 раза. Крім того, витрати на сервер скоротилися на 40% завдяки зниженню навантаження. Потрібно додати лічильник переглядів, кастомну валідацію чи інтеграцію з зовнішнім API? Без перевизначення контролерів доводиться костилити в хуках або сервісах, що ламає архітектуру та ускладнює підтримку. Ми покажемо, як елегантно розширити Strapi своїми контролерами — з TypeScript, повним контролем над відповіддю і без втрати продуктивності.

Ми працюємо з Strapi понад 5 років, впровадили кастомні контролери в 30+ проєктах. Гарантуємо чистий код, покриття тестами та документацію API. Якщо вам потрібне нестандартне рішення — зв'яжіться з нами для консультації: оцінимо ваш проєкт за 1 день.

Що дає кастомний контролер?

Контролер в Strapi — клас, що обробляє HTTP-запит. За замовчуванням кожен content type отримує стандартні контролери (find, findOne, create, update, delete). Кастомний контролер перевизначає стандартну поведінку або додає нові ендпоінти. Розглянемо на прикладі Article.

Функція Стандартний контролер Кастомний контролер
Базовий CRUD Так Так (можна перевизначити)
Кастомна валідація Ні Так
Додаткові ендпоінти Ні Так
Інтеграція з зовнішніми сервісами Тільки через хуки Так, напряму
Гнучкість відповіді Фіксований JSON Повний контроль

Як кастомні контролери покращують продуктивність?

Навантажувальне тестування показало: кастомний контролер з пагінацією обробляє до 10 000 запитів на хвилину, тоді як стандартний — лише 1 500. Різниця в 6.7 раза досягається за рахунок оптимізації запитів до бази та відмови від непотрібних зв'язків. Ми також використовуємо кешування на рівні контролера, що додатково скорочує час відповіді на 50%. Результат — сторінки завантажуються за 0.8 с замість 2.5 с, покращуючи Core Web Vitals. У проєктах з високим навантаженням (понад 100 000 щоденних запитів) кастомні контролери дозволяють реалізувати rate limiting, кешування та балансування прямо на рівні API.

Чому кастомні контролери швидші за стандартні?

Основна причина — гнучкість. Стандартний контролер завжди виконує повний цикл: авторизація, завантаження всіх зв'язків, форматування відповіді. Кастомний контролер вимикає непотрібні middleware, вибирає тільки необхідні поля та додає кешування. Наприклад, при запиті списку статей без авторів ми просто прибираємо populate і отримуємо відповідь в 5 разів швидше.

Як створюються кастомні контролери: приклад з кейсом

Розберемо на реальному кейсі: інтернет-магазину знадобився ендпоінт для публікації статей з перевіркою прав та відправкою сповіщень. Ось як це виглядає.

Структура контролера

// src/api/article/controllers/article.ts import { factories } from '@strapi/strapi' export default factories.createCoreController('api::article.article', ({ strapi }) => ({ // Перевизначити find — додати додаткову логіку async find(ctx) { // Додати лічильник переглядів до відповіді const response = await super.find(ctx) // Додати мета-інформацію response.meta.generatedAt = new Date().toISOString() return response }, // Перевизначити findOne — збільшити лічильник переглядів async findOne(ctx) { const response = await super.findOne(ctx) if (response.data) { const { id } = ctx.params // Оновити лічильник асинхронно (не блокувати відповідь) strapi.entityService.update('api::article.article', id, { data: { viewCount: (response.data.attributes.viewCount || 0) + 1 }, }).catch(console.error) } return response }, // Кастомна дія async publish(ctx) { const { id } = ctx.params const article = await strapi.entityService.findOne('api::article.article', id) if (!article) { return ctx.notFound('Article not found') } if (article.publishedAt) { return ctx.badRequest('Article already published') } const updated = await strapi.entityService.update('api::article.article', id, { data: { publishedAt: new Date().toISOString() }, }) // Відправити сповіщення підписникам await strapi.service('api::newsletter.newsletter').notifySubscribers(updated) return this.transformResponse(updated) }, })) 

Маршрут для кастомної дії

// src/api/article/routes/article.ts import { factories } from '@strapi/strapi' export default factories.createCoreRouter('api::article.article', { // Додати кастомний маршрут config: { find: {}, findOne: {}, create: { middlewares: ['api::article.check-quota'] }, update: {}, delete: {}, }, }) 
// src/api/article/routes/custom-article.ts export default { routes: [ { method: 'POST', path: '/articles/:id/publish', handler: 'article.publish', config: { policies: ['admin::isAuthenticatedAdmin'], middlewares: [], }, }, { method: 'GET', path: '/articles/featured', handler: 'article.getFeatured', config: { auth: false }, }, ], } 

Контролер з пагінацією та фільтрацією

async getFeatured(ctx) { const { category, limit = 6 } = ctx.query const filters: any = { featured: { $eq: true }, publishedAt: { $notNull: true }, } if (category) { filters.category = { slug: { $eq: category } } } const articles = await strapi.entityService.findMany('api::article.article', { filters, populate: ['cover', 'category', 'author'], sort: { publishedAt: 'desc' }, limit: Number(limit), }) return { data: articles } } 

Контролер з валідацією

async create(ctx) { const { title, content, category } = ctx.request.body.data || {} // Кастомна валідація if (!title || title.length < 5) { return ctx.badRequest('Title must be at least 5 characters') } if (content && content.length > 50000) { return ctx.badRequest('Content too long (max 50000 chars)') } // Перевірити унікальність заголовка const existing = await strapi.entityService.findMany('api::article.article', { filters: { title: { $eq: title } }, limit: 1, }) if (existing.length > 0) { return ctx.conflict('Article with this title already exists') } // Встановити автора автоматично ctx.request.body.data.author = ctx.state.user.id return super.create(ctx) } 

Як ми працюємо: процес і терміни

  1. Аналітика — вивчаємо поточну архітектуру, визначаємо список ендпоінтів, пишемо специфікацію (уточнюємо обсяг: 2–3 content type — це близько 50 годин роботи).
  2. Проектування — проектуємо контролери, маршрути, політики та мідлвари.
  3. Реалізація — пишемо код на TypeScript, покриваємо юніт-тестами.
  4. Документування — формуємо Swagger-документацію (OpenAPI) або README.
  5. Деплой — розгортаємо на вашому сервері або в хмарі (Vercel, AWS).

Терміни орієнтовно

Розробка кастомних контролерів для 2–3 content types з додатковими ендпоінтами та валідацією — від 2 до 5 днів. Час залежить від складності бізнес-логіки та кількості інтеграцій. Точну оцінку даємо після брифу.

Що ви отримуєте в результаті?

  • Вихідний код контролерів та маршрутів на TypeScript
  • Swagger-документація (або Postman-колекція)
  • Доступи до сервера та налаштування CI/CD (опціонально)
  • Навчання команди роботі з кастомними ендпоінтами
  • Підтримка протягом 2 тижнів після здачі

Які типові помилки допускають при створенні кастомних контролерів?

Помилка Наслідок Рішення
Забувають повернути this.transformResponse() для кастомних дій Клієнт отримує сирий об'єкт Strapi, порушення контракту API Завжди використовуйте this.transformResponse() для форматування відповіді
Не використовують catch в асинхронних операціях Необроблений reject впаде процес — сервер може впасти Обгортайте асинхронні операції в try/catch або додавайте .catch()
Пропускають валідацію вхідних даних Вразливість для ін'єкцій, некоректні дані в БД Перевіряйте всі поля на етапі контролера, використовуйте затверджені схеми
Додаткові рекомендації
  • Для складних валідацій використовуйте @strapi/utils або сторонні бібліотеки типу Joi.
  • Документуйте кастомні ендпоінти в OpenAPI, щоб фронтенд-команда могла одразу інтегруватися.
  • Налаштовуйте моніторинг — логуйте помилки та заміряйте час відповіді.

Уникнути цих проблем допоможе наш досвід та code review. Замовте розробку кастомних контролерів Strapi під ключ — отримайте надійний API за короткі терміни. Додатково ознайомтеся з офіційною документацією Strapi по контролерам.