DDD на фронте и бэке

Domain-Driven Design одинаково применим к клиенту и серверу. Через Metacom вызовы домена прозрачны: UI зовёт domain.method(...), не зная, что метод исполняется на сервере.

Идея

DDD говорит: пиши доменный код, всё остальное (БД, HTTP, UI-framework) — инфраструктура, от которой надо абстрагироваться.

В большинстве проектов это эфемерная цель: на бэке domain layer есть, но дальше всё равно лежит ORM и HTTP-controllers. На фронте domain layer часто отсутствует — есть только Redux и компоненты.

DDD-стэк

Frontend                Backend
  ├─ UI                   ├─ HTTP/RPC layer
  ├─ Application          ├─ Application
  ├─ Domain  ◄── ═══►     ├─ Domain
  └─ Infrastructure       └─ Infrastructure

В Metarhia доменный код один и тот же — может исполняться и на клиенте, и на сервере. Слой application (use cases) превращается в переброс к domain. HTTP-слой не пишется — его делает Impress.

автор про domain

«Пишем только эту часть, только domain код. Больше ничего не пишем. Кроме него в метархии вообще ничего нет. Весь application состоит из domain кода.»

Это радикальная позиция: убираем application layer, оставляем только domain.

Пример: Todo-list в DDD

// domain/todo.js
const add = (list, todo) => [...list, todo];
const remove = (list, id) => list.filter(t => t.id !== id);
const toggle = (list, id) => list.map(t =>
  t.id === id ? { ...t, done: !t.done } : t
);
  • Чистые функции.
  • Не знают про БД, UI, HTTP.
  • Работают и на клиенте, и на сервере.

Endpoint vs domain

  • Endpoint — то, что слушает HTTP/WS. В Metacom это RPC-метод, прокидывает в domain.
  • Domain — чистая бизнес-логика. В обычном Node-проекте часто слиты в один файл controller'а.

В Metarhia endpoint в api/, domain в domain/, и api/x.js обычно просто module.exports = domain.x.

Local-first как продолжение

В local-first схема:

UI → domain → reactive local store
                ↓ sync layer (CRDT + Metacom)
              server-side domain
                ↓
              сервер-сайд store

Domain layer на клиенте и сервере одинаковый. Местоположение исполнения — деталь конфигурации.

Redux как СУБД

В современном фронте Redux выполняет роль локальной БД (state store). Это уже DDD-friendly: компоненты не лезут в API напрямую, всегда через store.

В local-first идея усиливается: Redux/Pinia/MobX становятся настоящей реактивной СУБД (с persistence и sync).

Чем отличается от mainstream React+NestJS

mainstream Metarhia DDD
Domain layer на фронте редко обязательно
Domain code shared редко да
Слой application пишется минимум
Слой инфраструктуры пишется даёт фреймворк

🎓 Источники

См. также