Розробка інтернет-магазину на Spree Commerce
Spree — Rails-рух з відкритим вихідним кодом, який існує з 2008 року. На відміну від Vendure та commercetools, Spree — monolithic-first: він встраювається в Rails-приложення як Engine і працює з тією ж базою даних. Починаючи з версії 4.3 додався headless-режим через REST API v2, що дозволяє використовувати Spree як backend для React/Vue фронтенду.
Два режими використання
Monolith (класичний): Spree працює як Rails Engine всередину вашого Rails-приложення. Storefront рендеріється сервером (ERB + Turbo), Admin UI вбудований. Підходить для команд з Rails-експертизою та середнім трафіком.
Headless:
Spree надає REST API v2 (/api/v2/storefront) та стандартний React storefront (spree/storefront). Storefront розгортається окремо. Цей режим стає основним з Spree 5.x.
Архітектура: Rails Engine
# Gemfile
gem 'spree', '~> 4.10'
gem 'spree_auth_devise', '~> 4.6'
gem 'spree_gateway', '~> 3.10'
gem 'spree_backend', '~> 4.10' # Admin UI
gem 'spree_sample', '~> 4.10' # Тестові дані
# Для headless:
gem 'spree_api', '~> 4.10'
bundle install
bin/rails g spree:install
bin/rails g spree:auth:install
bin/rails db:migrate
bin/rails db:seed
Після встановлення доступні:
-
/admin— панель управління -
/api/v2/storefront— REST API для фронтенду -
/— класичний storefront (якщо встановленspree_frontend)
Модель даних
Spree має усталену схему:
Spree::Store # Мультимагазинність
├── Spree::Taxon # Категорії (вложені через ancestry)
├── Spree::Product
│ ├── Spree::Variant # Варіанти = SKU
│ ├── Spree::Price # Ціна за варіант за валютою
│ └── Spree::Image
├── Spree::Order
│ ├── Spree::LineItem
│ ├── Spree::Payment
│ └── Spree::Shipment
└── Spree::User # через spree_auth_devise
REST API v2: Headless режим
// lib/spreeClient.ts
import { makeClient } from "@spree/storefront-api-v2-sdk";
export const client = makeClient({
host: process.env.NEXT_PUBLIC_SPREE_URL!,
});
// Отримати список товарів
const products = await client.products.list(
{},
{
include: "default_variant,images,taxons",
filter: { taxons: taxonId },
sort: "name",
page: 1,
per_page: 24,
}
);
// Створити кошик
const cart = await client.cart.create();
const orderToken = cart.success().data.attributes.token;
// Додати товар
await client.cart.addItem(
{ orderToken },
{
variant_id: variantId,
quantity: 1,
}
);
// Checkout: адреса
await client.checkout.orderUpdate(
{ orderToken },
{
order: {
ship_address_attributes: {
firstname: "Іван",
lastname: "Петров",
address1: "вул. Ленина 1",
city: "Москва",
country_iso: "RU",
zipcode: "101000",
phone: "+79001234567",
},
},
}
);
Кастомізація бізнес-логіки
Spree використовує Decorator pattern для розширення моделей без форка:
# app/models/spree/product_decorator.rb
module Spree
module ProductDecorator
def bundle?
bundle_parts.any?
end
def effective_price_for(quantity)
if quantity >= 10
price * 0.9
elsif quantity >= 5
price * 0.95
else
price
end
end
end
end
Spree::Product.prepend(Spree::ProductDecorator)
Промоакції — окрема система (Spree::Promotion):
promotion = Spree::Promotion.create!(
name: "Літня скидка 15%",
code: "SUMMER15",
starts_at: Date.today,
expires_at: 3.months.from_now,
usage_limit: 1000
)
promotion.actions.create!(
type: "Spree::Promotion::Actions::CreateAdjustment",
calculator: Spree::Calculator::FlatPercentItemTotal.create!(
preferred_flat_percent: 15.0
)
)
Етапи розробки
| Етап | Опис | Терміни |
|---|---|---|
| Setup + конфігурація | Rails app, Spree install, БД | 2–3 дні |
| Каталог + імпорт товарів | Rake задачі, CSV/API імпорт | 4–8 днів |
| Кастомна бізнес-логіка | Декоратори, промоції, доставка | 5–10 днів |
| Фронтенд (Headless) | Next.js + Spree SDK | 10–20 днів |
| Платіжні інтеграції | 2–3 провайдери | 4–6 днів |
| Admin UI кастомізація | Додаткові розділи | 3–5 днів |
| Разом | 28–52 дні |
Технічний стек
- Backend: Ruby 3.2 + Rails 7.1 + Spree 4.10
- БД: PostgreSQL 15 (складні промоції, ancestry дерева)
- Кеш: Redis (Solid Cache або Redis-store)
- Шрифти: Sidekiq для фонових задач (email, синхронізація)
-
Пошук: Elasticsearch через
searchkickабо pg_search -
Фронтенд: Next.js 14 +
@spree/storefront-api-v2-sdk







