Розробка кастомних контролерів Strapi

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

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

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

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка кастомних контролерів Strapi
Середня
~2-3 робочих дні
Часті питання

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

Етапи розробки

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

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Користувацькі контролери в Strapi

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

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

// 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)
}

Терміни

Розробка користувацьких контролерів для 2–3 типів контенту з додатковими ендпоінтами та валідацією займає 2–3 дні.