Скажем, у меня есть классический ограниченный контекст клиента и команда MakeCustomerPreferred
и что у меня есть некоторые проблемы с перекрестными разрезами, такие как ведение журнала и авторизация. Хотя мы рассмотрели способ решения этих проблем с перекрестными ограничениями, мне очень интересно узнать, где мы хотим записать информацию о пользователе или службе, которая отвечала за выдачу команды в самих событиях домена.Запись службы выдачи и пользователь с событиями в системе CQRS/ES
Пример событие:
interface CustomerMadePreferred {
customerId: string,
issuingService: string,
issuingUser: string,
}
Пример команда:
interface MakeCustomerPreferred {
customerId: string
}
Используя команду выше, мы бы не хватаем контекст, в котором подробно пользователь эмиссионного и обслуживание. Мы могли бы потребовать от клиента указать значения для issuingService
и issuingUser
как часть команды, но проблема в том, что обычно это команда, представленная клиентом, и позволяет предположить в этом случае, что клиент является веб-браузером вне контроля приложения где мы не можем контролировать, какие значения пользователь может представить в команде. Кроме того, мы можем определить эти значения в целом, если наша служба находится за веб-интерфейсом ReSTful или JSON Web, используя такие вещи, как токены OAuth. Это оставляет мне несколько очевидных стратегий.
Возможные стратегии:
- Включите
issuingService
иissuingUser
с командой, а затем проверить их от значений, определенных из контекста AUTH. Это позволяет команде, выданной клиентом, быть идентичной команде, обработанной обработчиком, и упрощает реализацию обработчика, поскольку ему нужен только командный параметр и не передается контекст. - Извлечение
issuingService
иissuingUser
из контекста auth и добавил/ввел эти данные в команду, переданную обработчику команд. Это облегчает задачу для клиентов, выдающих исходную команду, но контракт команды немного отличается между обработчиком команд и клиентом. Пример:Object.assign({}, makeCustomerPreferredCommand, authContext);
- Передайте контекст auth как отдельный аргумент обработчику команд или сделайте его доступным из службы, которую может вызывать обработчик команд. Это сохраняет контракт команды, но усложняет реализацию обработчика команд.
Я склоняюсь к опции и главным образом потому, что, кажется, позволяют функциональный подход к реализации команды обработчика. Возможно, я оставляю какой-то вариант или пропускаю некоторые детали, которые могут отображать в том числе issuingService
и issuingUser
в случае ненужных событий.
UPDATE: Альтернативы, позволяет называть его вариантом , может быть, чтобы не включать эти данные в созданном CustomerMadePreferred события, а вместо ручки и испускать отдельные CommandIssued
события, которые могут содержать ключ какого-то, что может использоваться для связывания информации эмитента с событиями, выпущенными обработчиком команд.
Согласно технической реализации, когда я думаю о той же проблеме, мой план состоит в том, чтобы добавить некоторые метаданные к событию. Таким образом, событие останется объектом домена, но я могу приложить к нему некоторые технические метаданные для идентификации контекста. –
@jpierson нет разницы между 2. и 3. насколько * команда немного отличается между обработчиком команд и клиентом *, есть ли? – guillaume31
@ guillaume31, различия между 2 и 3, возможно, но тонкие, но с точки зрения того, как можно будет писать модульное тестирование вокруг этих или любых других отражающих инструментов вокруг типов команд, будет сильно затронуто. Контракт классов/функций обработчика команд также будет затронут. – jpierson