Розробка кастомних middleware Strapi

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

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

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

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка кастомних middleware 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

Користувацькі middleware в Strapi

Middleware в Strapi — це функції, які виконуються перед або після обробки запиту контролером. Вони працюють як Express/Koa middleware. Вони застосовуються глобально (до всіх маршрутів) або до конкретних маршрутів.

Типи middleware

Strapi розрізняє:

  • Global middleware — застосовується до всіх запитів, зареєстровано в config/middlewares.js
  • Route middleware — застосовується до конкретних маршрутів, зареєстровано в конфігурації маршруту

Global Middleware — логування

// src/middlewares/request-logger.ts
export default (config: any, { strapi }: any) => {
  return async (ctx: any, next: any) => {
    const start = Date.now()

    await next()

    const duration = Date.now() - start
    const { method, url, status } = ctx

    if (duration > 1000) {
      strapi.log.warn(`Slow request: ${method} ${url} — ${duration}ms (${status})`)
    }

    strapi.log.debug(`${method} ${url} — ${duration}ms [${status}]`)
  }
}
// config/middlewares.js — зареєструвати глобально
module.exports = [
  'strapi::logger',
  'strapi::errors',
  'strapi::security',
  'strapi::cors',
  'global::request-logger',   // користувацький middleware
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
]

Global Middleware — Rate Limiting

// src/middlewares/rate-limit.ts
const requests = new Map<string, number[]>()

export default (config: any) => {
  const { maxRequests = 100, windowMs = 60_000 } = config

  return async (ctx: any, next: any) => {
    const ip = ctx.request.ip
    const now = Date.now()
    const windowStart = now - windowMs

    // Очистити старі запити
    const timestamps = (requests.get(ip) || []).filter(t => t > windowStart)

    if (timestamps.length >= maxRequests) {
      ctx.status = 429
      ctx.body = { error: 'Too Many Requests' }
      ctx.set('Retry-After', String(Math.ceil(windowMs / 1000)))
      return
    }

    timestamps.push(now)
    requests.set(ip, timestamps)

    await next()
  }
}
// config/middlewares.js
{
  name: 'global::rate-limit',
  config: { maxRequests: 100, windowMs: 60000 }
}

Route Middleware — перевірка підписки

// src/middlewares/check-subscription.ts
export default (config: any, { strapi }: any) => {
  return async (ctx: any, next: any) => {
    const userId = ctx.state.user?.id

    if (!userId) {
      ctx.unauthorized('Authentication required')
      return
    }

    const user = await strapi.entityService.findOne(
      'plugin::users-permissions.user',
      userId,
      { populate: ['subscription'] }
    )

    if (!user?.subscription?.active) {
      ctx.forbidden('Active subscription required')
      return
    }

    await next()
  }
}
// src/api/premium-content/routes/premium-content.ts
export default {
  routes: [
    {
      method: 'GET',
      path: '/premium-content',
      handler: 'premium-content.find',
      config: {
        middlewares: ['api::premium-content.check-subscription'],
      },
    },
  ],
}

Middleware для трансформації відповіді

// src/middlewares/add-computed-fields.ts
export default () => {
  return async (ctx: any, next: any) => {
    await next()

    // Додати поля до відповіді API після обробки
    if (ctx.url.startsWith('/api/products') && ctx.body?.data) {
      const transform = (item: any) => ({
        ...item,
        attributes: {
          ...item.attributes,
          // Розрахувати знижку
          discountPercent: item.attributes.originalPrice
            ? Math.round((1 - item.attributes.price / item.attributes.originalPrice) * 100)
            : 0,
        },
      })

      if (Array.isArray(ctx.body.data)) {
        ctx.body.data = ctx.body.data.map(transform)
      } else {
        ctx.body.data = transform(ctx.body.data)
      }
    }
  }
}

Middleware для багатомовних URL

// src/middlewares/locale-redirect.ts
const localeMap: Record<string, string> = {
  'ru-RU': 'ru',
  'en-US': 'en',
  'uk-UA': 'uk',
}

export default () => {
  return async (ctx: any, next: any) => {
    // Якщо у заголовку Accept-Language є локаль, додати у query
    if (!ctx.query.locale) {
      const acceptLang = ctx.get('Accept-Language')?.split(',')[0] || 'ru'
      const locale = localeMap[acceptLang] || acceptLang.split('-')[0] || 'ru'
      ctx.query.locale = locale
    }

    await next()
  }
}

Терміни

Розробка набору middleware (rate limiting, логування, трансформація відповіді) займає 1–2 дні.