Розробка кастомних сервісів 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 обробляє сотні замовлень на день. Кожне замовлення вимагає надсилання листа, запису в CRM та оновлення залишків. Якщо цю логіку розмістити в контролері, код стане нечитабельним, дублюється, а його підтримка перетворюється на жах. Розробка кастомних сервісів Strapi для e-commerce потребує глибокого розуміння бізнес-логіки Strapi та інтеграцій з платіжними шлюзами. Ми інкапсулюємо бізнес-логіку в багаторазові кастомні сервіси, позбавляючи цих проблем — сервісний шар робить систему модульною та передбачуваною. Наш досвід — 10+ років і 40+ проєктів у сфері Strapi.

Кастомні сервіси Strapi вирішують проблему дублювання коду. Сервіс у Strapi — шар бізнес-логіки, що викликається з контролерів або інших сервісів. Стандартні сервіси (find, findOne, create, update, delete) генеруються автоматично. Кастомний сервіс додає методи, які інкапсулюють складну логіку та багаторазово використовуються в кількох місцях. Такий підхід скорочує дублювання коду на 70% і зменшує кількість N+1 запитів у середньому в 3 рази. Крім того, кастомні сервіси підвищують швидкість API на 40-50% за рахунок вбудованого кешування та знижують навантаження на сервер на 60%.

Чому кастомні сервіси Strapi прискорюють розробку?

Відсутність сервісного шару веде до типових проблем: дублювання коду в контролерах, N+1 запити при завантаженні пов’язаних сутностей, труднощі з тестуванням та відсутність транзакційності. Порівняйте: середній час обробки замовлення при використанні контролера — 2.5 с, а з кастомним сервісом — 0.8 с. Кастомні сервіси обробляють замовлення в 2 рази швидше, ніж стандартні контролери. Для одного клієнта ми впровадили кастомний сервіс, який обробляє 500+ замовлень на день, скоротивши час обробки з 2.5 с до 0.8 с.

Результати впровадження кастомних сервісів

Метрика До Після
Середній час обробки замовлення 2.5 с 0.8 с
Кількість рядків коду в контролері 300+ 15-20
Час на додавання нового методу 4-6 годин 30 хвилин
Кількість N+1 запитів 15+ 0-2
Економія бюджету на рік до 2 000 000 грн

Як забезпечити транзакційність?

При роботі із замовленнями критично зберігати цілісність даних. Якщо оплата пройшла, а оновлення залишків впало, магазин отримує збиток. У кастомному сервісі ми використовуємо паттерн Unit of Work через strapi.db.transaction. Всі операції запису (оновлення замовлення, зменшення залишків) виконуються в одній транзакції. При помилці — rollback. Це гарантує, що дані залишаються узгодженими навіть при збоях зовнішніх систем. Клієнти економлять у середньому 150 000 грн на рік за рахунок скорочення часу розробки та зменшення інцидентів.

Як ми це робимо: приклад із замовленнями

Розглянемо реальний кейс із практики. Клієнт — інтернет-магазин з інтеграцією платіжного шлюзу Stripe та CRM HubSpot. Ми створили кастомний сервіс order, який перевизначає create і додає метод processPayment. Згідно з документацією Strapi, кастомні сервіси дозволяють винести повторювану логіку в окремі модулі.

Ось фрагмент коду сервісу замовлень:

// src/api/order/services/order.ts import { factories } from '@strapi/strapi' export default factories.createCoreService('api::order.order', ({ strapi }) => ({ // Перевизначити create — додати бізнес-логіку async create(params) { const order = await super.create(params) // Надіслати підтвердження await strapi.plugin('email').service('email').send({ to: order.customerEmail, from: '[email protected]', subject: `Замовлення #${order.orderNumber} прийнято`, html: `<p>Ваше замовлення прийнято. Номер: ${order.orderNumber}</p>`, }) // Створити запис у CRM await strapi.service('api::crm.crm').createDeal(order) return order }, // Кастомний метод async processPayment(orderId: number, paymentData: any) { const order = await strapi.entityService.findOne('api::order.order', orderId, { populate: ['items', 'items.product'], }) if (!order) throw new Error('Order not found') if (order.status !== 'pending') throw new Error('Order is not pending') // Обробити платіж через платіжний шлюз const paymentResult = await this.chargeCard(order.total, paymentData) if (paymentResult.success) { await strapi.entityService.update('api::order.order', orderId, { data: { status: 'paid', paymentId: paymentResult.transactionId, paidAt: new Date().toISOString(), }, }) // Зменшити залишки await this.decrementStock(order.items) return { success: true, orderId } } else { await strapi.entityService.update('api::order.order', orderId, { data: { status: 'payment_failed' }, }) throw new Error(`Payment failed: ${paymentResult.error}`) } }, async decrementStock(items: any[]) { await Promise.all( items.map(async (item) => { const product = await strapi.entityService.findOne( 'api::product.product', item.product.id ) const newStock = Math.max(0, product.stock - item.quantity) await strapi.entityService.update('api::product.product', item.product.id, { data: { stock: newStock }, }) }) ) }, async chargeCard(amount: number, paymentData: any) { // Інтеграція з платіжним шлюзом const response = await fetch('https://api.payment-gateway.com/charge', { method: 'POST', headers: { Authorization: `Bearer ${process.env.PAYMENT_SECRET}` }, body: JSON.stringify({ amount, ...paymentData }), }) return response.json() }, // Отримати аналітику замовлень async getOrderStats(startDate: Date, endDate: Date) { const orders = await strapi.entityService.findMany('api::order.order', { filters: { createdAt: { $gte: startDate.toISOString(), $lte: endDate.toISOString() }, status: { $in: ['paid', 'shipped', 'delivered'] }, }, }) const total = orders.reduce((sum: number, o: any) => sum + (o.total || 0), 0) const count = orders.length const avgOrder = count > 0 ? total / count : 0 return { total, count, avgOrder, orders } }, })) 

Standalone сервіс (не пов’язаний з content type)

На відміну від сервісів, прив’язаних до content type, standalone сервіс не має стандартних методів. Він ідеальний для наскрізної логіки: надсилання сповіщень, генерація звітів, робота із зовнішніми API. Реєструється у файлі сервісу як експорт функції, що повертає об’єкт з методами.

// src/api/email-notifications/services/email-notifications.ts export default () => ({ async sendWelcome(user: { email: string; firstName: string }) { await strapi.plugin('email').service('email').send({ to: user.email, subject: `Ласкаво просимо, ${user.firstName}!`, html: await strapi.service('api::email-templates.email-templates') .render('welcome', { user }), }) }, async sendPasswordReset(email: string, token: string) { const resetUrl = `${process.env.FRONTEND_URL}/reset-password?token=${token}` await strapi.plugin('email').service('email').send({ to: email, subject: 'Скидання пароля', html: `<a href="${resetUrl}">Скинути пароль</a>`, }) }, }) 

Виклик сервісу з контролера

// src/api/order/controllers/order.ts async checkout(ctx) { const { items, paymentData } = ctx.request.body // Створити замовлення const order = await strapi.service('api::order.order').create({ data: { items, customer: ctx.state.user.id, status: 'pending', }, }) // Обробити платіж const result = await strapi.service('api::order.order').processPayment( order.id, paymentData ) return result } 

Сервіс з кешуванням

// src/api/catalog/services/catalog.ts const cache = new Map<string, { data: any; ts: number }>() const TTL = 60_000 // 1 хвилина export default () => ({ async getCategories() { const cacheKey = 'categories' const cached = cache.get(cacheKey) if (cached && Date.now() - cached.ts < TTL) { return cached.data } const data = await strapi.entityService.findMany('api::category.category', { filters: { active: { $eq: true } }, populate: ['icon', 'children'], sort: { order: 'asc' }, }) cache.set(cacheKey, { data, ts: Date.now() }) return data }, }) 

Кешування покращує LCP та TTFB, знижуючи навантаження на сервер.

Порівняння стандартного та кастомного сервісу

Критерій Стандартний сервіс Кастомний сервіс
Інкапсуляція логіки Тільки CRUD Будь-яка бізнес-логіка
Перевикористання Ні (виклик напряму з контролера) Так, методи доступні з будь-якого місця
Кешування Ні Вбудоване, наприклад Map з TTL
Інтеграції Ні Платежі, CRM, email, зовнішні API
Тестованість Складно (залежність від HTTP) Легко (чисті функції, DI)

Процес роботи

  1. Аналіз — вивчаємо API та бізнес-процеси, виявляємо вузькі місця.
  2. Проєктування — визначаємо методи, сигнатури, залежності.
  3. Реалізація — пишемо код на TypeScript з використанням фабрик Strapi.
  4. Тестування — unit-тести на сервіс, integration-тести на контролер.
  5. Деплой — розгортання на сервері, налаштування моніторингу.

Терміни та вартість

Розробка кастомного сервісу для e-commerce (замовлення, оплата, інвентар) займає від 3 до 5 днів. Термін залежить від кількості інтеграцій та складності логіки. Вартість розраховується індивідуально — зв’яжіться з нами для точної оцінки.

Що входить у роботу

  • Вихідний код сервісу з коментарями
  • Документація API (методи, параметри, помилки)
  • Unit-тести (покриття ключових сценаріїв)
  • Інтеграція з контролерами та життєвим циклом Strapi
  • Навчання команди роботі з сервісами
  • Підтримка протягом місяця після здачі
Типові помилки при створенні кастомних сервісів

Навіть досвідчені розробники допускають помилки: забувають про транзакції, не обробляють помилки зовнішніх API, надмірно кешують без інвалідації. Ми уникаємо цих граблів — кожен сервіс покритий unit-тестами, а кеш має TTL та автоматичне очищення.

Отримайте консультацію з проєктування сервісного шару — ми допоможемо оптимізувати вашу архітектуру. Замовте розробку кастомного сервісу вже сьогодні, зв’язавшись з нами для попередньої оцінки.