Короткий ответ
Границы сервиса следует проводить по бизнес-домену и данным, которыми он владеет (bounded context), а не по техническим слоям; «уведомления» выделяются в отдельный сервис, если у них свой жизненный цикл данных и узкий контракт взаимодействия с остальной системой.
Как это работает подробнее
Сначала определяют, какие данные и операции логически принадлежат домену «уведомления» (шаблоны, история отправок, настройки каналов), затем формализуют интерфейс (отправить уведомление, получить статус) и переносят только эту ответственность.
Пример кода
Схема
До: OrderService -> notifications_table (общая БД монолита)
После: OrderService -- событие "order.created" --> Notification Service -> своя БДЧто использовать на практике
- Практика. Хороший признак готовности — модуль уже внутри монолита слабо связан с остальными (мало взаимных вызовов, собственная таблица/схема данных), и команда может развивать и деплоить notification независимо, не блокируя релизы остальной системы.
Подводные камни
- Риск. Выделять сервис по техническому принципу («всё, что рассылает email»), не разделяя данные — новый сервис обращается к общей БД монолита, что не даёт реальной изоляции.