🧩 Как работать с данными в модульном монолите
В модульном монолите мы стремимся к максимальной независимости модулей, что также включает и работу с данными. Хотя все модули могут использовать общую БД, необходимо поддерживать строгую изоляцию данных для каждого модуля. Это предотвращает сильную связанность, упрощает рефакторинг и сохраняет возможность будущего выделения модулей в отдельные микросервисы.
🔐 Основные принципы изоляции данных
Также как и при построении взаимодействия между модулями, для того чтобы соблюдать изоляцию данных в модульном монолите, нужно придерживаться тех же самых принципов построения модульного монолита. В случае с данными они будут выглядеть примерно так:
- Каждый модуль имеет свою модель данных (таблицы, сущности, репозитории).
- Модуль не обращается к данным других модулей напрямую.
- Модуль предоставляет доступ к своим данным через API или доменные события.
🔧 Подходы к изоляции данных
Логическая изоляция (в рамках одной схемы БД)
В рамках данного подхода мы не разделяем физически данные между модулями, а используем логическую изоляцию, что позволяет нам работать с данными в рамках одной схемы БД. Для каждого модуля мы определяем список таблиц, с которыми он может работать. Модули не могут обращаться к данным других модулей напрямую, а только через API или доменные события. На уровне БД мы можем использовать префиксы для таблиц, содержащих название модуля. Например, таблица users модуля auth будет называться auth_users.
Изоляция на уровне схемы данных
В данном подходе для каждого модуля мы создаем свою схему данных. Этот вариант позволяет еще больше изолировать данные, но также требует большего количества работы с БД. Плюс, используя ORM, нам нужно будет явно указывать схему данных для каждого модуля. Например, модуль auth будет использовать схему auth. Этот подход выглядит наиболее компромиссным для старта разработки. Если потребуется мигрировать таблицы данных между схемами БД, то в большинстве случаев процедура миграции будет содержать только переименование схемы у таблицы.
Изоляция на уровне базы данных
В данном подходе для каждого модуля мы создаем свою базу данных. Этот подход гарантирует (при определенных условиях), что не будет общих для нескольких модулей транзакций. Но данный подход требует большого количества работы с БД. К тому же, если мы захотим мигрировать данные между базами данных, то нам нужно будет делать процедуры миграции. Что может сильно усложнить работу на первых этапах разработки.
Отдельные скрипты миграции для каждого модуля.
В независимости от того, как будем реализовывать изоляцию данных, необходимо будет использовать отдельные скрипты миграции для каждого модуля. В идеальном случае — миграции для каждого модуля запускаются отдельным шагом CI/CD и записываются в свои уникальные таблицы в рамках каждого модуля.
📌 Заключение
Следуя этим подходам, вы сможете построить модульный монолит, который будет не только прост в разработке и развертывании, но и сохранит гибкость для эволюции и масштабирования, когда бизнес потребует этого. Изоляция данных — это про управляемость, надёжность и эволюцию архитектуры.
Модульный монолит должен:
- изолировать модули и на уровне кода, и на уровне данных;
- не допускать «сквозных зависимостей»;
- предоставлять явные способы доступа к своим данным.
Это позволит легко развивать продукт, масштабировать команды и, при необходимости, плавно перейти к микросервисам — без сильной боли.
Подпишись на мой телеграм-канал
#SoftwareArchitecture #DDD #microservices #monolith #modularmonolith.