Недавно я пытался заставить мое веб-приложение использовать отдельные слои.
Если я правильно понимаю концепцию, мне удалось извлечь:
ДоменСлой Здесь находятся мои основные доменные сущности, совокупные корни, объекты-значения. Я вынужден иметь чистую модель предметной области, то есть здесь у меня нет определений сервисов.Единственное, что я здесь определяю, это репозитории, которые на самом деле скрыты, потому что инфраструктура Axon реализует это для меня автоматически.
Уровень инфраструктуры Здесь Axon реализует определения репозитория для моих агрегатов вслой домена
Уровень проецирования Здесь реализованы обработчики событий для проецирования данных для модели чтения с использованием MongoDB для ее сохранения.Он не знает ничего, кроме модели событий (простые классы данных в kotlin)
Прикладной уровень Здесь начинается путаница.
Контроллерслой Здесь я реализую контроллеры GraphQL / REST, этот уровень контроллера использует модель команд и запросов, что означает, что он обладает знаниями о командах уровня домена, а также о модели запросов уровня проекции.
Как я уже упоминал, путаница начинается с прикладного уровня, позвольте мне немного объяснить это на упрощенном примере.
Учитывая, что я хочу, чтобы модель предметной области реализовала логику борьбы с покемонами.Мне нужно использовать PokemonAPI, который предоставил бы мне данные статистики имен Pokemon и т. Д., Это был бы внешний API, который я использовал бы, чтобы получить некоторые данные.
Допустим, я бы реализовал домен следующим образом: (Имейте в виду, что я расширил эту реализацию, поэтому она вызывает некоторые проблемы, которые у меня возникают в моем собственном домене)
Pokemon {
id: ID
}
PokemonFight {
id: ID
pokemon_1: ID
pokemon_2: ID
handle(cmd: Create) {
publish(PokemonFightCreated)
}
handle(cmd: ProvidePokemonStats) {
//providing the stats for the pokemons
publish(PokemonStatsProvided)
}
handle(cmd: Start) {
//fights only when the both pokemon stats were provided
publish(PokemonsFought)
}
Поток данных между слоями будет выглядеть следующим образом.
Пользователь -> [HTTP] -> Контроллер -> [CommandGateway] -> (Приложение | Домен) -> [EventGateway] -> (Приложение| Domain)
Предположим, что два покемона созданы, и сценарий использования боя покемонов в основном состоит в том, что при его создании предоставляется статистика, а затем, когда предоставляется статистика, бой автоматически начинается.
Эта логика варианта использования может быть решена с помощью обработчика событий или даже саги.
Однако, как вы видите в агрегате PokemonFight, есть команда [ProvidePokemonStats], которая в основном предоставляет их статистику, как и мой домен.не знаю, как получить такие данные, эти данные предоставляются с PokemonAPI.
Это немного смущает меня, потому что сценарий использования потребуетсяo быть реализованным на обоих уровнях, в приложении (поэтому он предоставляет статистику с использованием внешнего API), а также в домене?вариант использования домена будет просто использовать чисто доменные понятия.Но разве у меня не должно быть одного места для вариантов использования?
Если я подумаю об этом, единственная цель, с помощью которой обработчик саг / событий, который живет на прикладном уровне, состоит в том, чтобы предоставлять надлежащие данные моему домену, чтобы он могпродолжить с его вариантами использования.Поэтому, когда происходит сбой внешнего API, я отправляю команду в домен, и затем он может решить, что делать.
Например, я мог бы просто поместить каждый обработчик саг / событий в приложение, поэтому, когда я решу изменить некоторую автоматизациюЯ точно знаю, какой модуль мне нужно отредактировать и где его найти.
Другая путаница - это когда у меня несколько доменов, и я хочу создать сценарий использования, который использует многие из них и соединяет данные между нимив моем мозгу сразу же прозвучало, что это должен быть прикладной уровень, который будет использовать доменные API для управления прецедентом, потому что я не думаю, что мне следует добавлять зависимость другого домена в основной.
TL; DR
Какой уровень должен отвечать за реализацию автоматизированного процесса между агрегатами (может быть единичным, но вы понимаете, что я имею в виду), если процессу требуются некоторые внешние данные API.
Какой уровень должен отвечать за внедрение автоматизированного процесса между агрегатами, которые живут в разных доменах / микросервисах.
Заранее спасибо, и мне также жаль, если то, что я написал, звучит сбивающим с толку или слишком много текста, однако любые ответы о размещении приложений DDD и правильном расположении компонентов я был бы очень признателен.