Аксон: мультикоманда для одного агрегата - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть довольно хорошая идея для тонкой гранулированной обработки команд API.

Наш веб-API должен предоставлять одну простую конечную точку update, но вы можете предоставить ей несколько команд.Примерно так:

POST /myAggregate/12345/update
[
  { command1Name: "command1Data" },
  { command2Name: "command2Data" },
  { command3Name: "command3Data" }
]

В Аксоне это кажется довольно сложным.Особенно в сочетании с @AggregateVersion.


Моя первая идея состояла в том, чтобы иметь новый UpdateWrapperCommand.который внутренне имеет List commands.И затем в Aggregate вы используете рефлексию для вызова правильных @CommandHandler методов:

class UpdateWrapperCommand {
  List commands;
}

@Aggregate
class MyAggregate {
  // id, version, constructor, etc. pp.

  @CommandHandler
  public void handle(SomeCommand cmd) { ... }

  @CommandHandler
  public void handle(UpdateWrapperCommand cmd) {
    // iterate over cmd.commands
    // iterate over this.getClass().getMethods()
    // find correct method(s), and invoke it
  }
}

Но когда @CommandHandler s также использует @MetaData и / или Spring Bean, то это становится действительноhard.


Моя вторая идея заключалась в простом вызове commandGateway.send в цикле.Но это взрывается, потому что @TargetAggragateVersion должно быть установлено для каждой команды, и вы должны ждать завершения каждой команды, прежде чем отправлять следующую.Это нехорошо.


У вас есть какие-нибудь идеи для этого?

Он должен загрузить агрегат один раз, а затем выполнить все команды.

И, возможно, даже есть некоторыеПоведение, подобное транзакции: применить все полученные события или ничего.

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Я думаю, что вам лучше всего решить эту проблему прямо сейчас, без необходимости ждать проблемы , которую вы добавили в систему отслеживания проблем Axon Framework, - добавить Внешнюю командуОбработчик .

Внешний обработчик команд - это обычный компонент с аннотированной функцией @CommandHandler.Этот метод будет обрабатывать ваш UpdateWrapperCommand и знать, как выполнить отдельные команды для каждой полезной нагрузки, содержащейся в нем.

Оптимизация загрузки Aggregate, как вы предлагаете, однако, действительно связана с реализацией решения Batch Command.,Хотя это, безусловно, выполнимо в рамках, эта функция еще не на месте.Я бы посоветовал вам следить за созданной вами проблемой , чтобы следить за ее ходом.

Надеюсь, это поможет вам, Бенджамин!

0 голосов
/ 20 февраля 2019

Если транзакция означает «все или ничего», то, вероятно, границы каждой команды плохо смоделированы.

Без понимания предметной области я бы сказал, что возможны следующие варианты:

1 Обернуть все команды только в одну и применить к одному агрегату со всеми ручками.

2 Применить все командысамостоятельно и в случае любого сбоя примените компенсирующие действия.

3 Не использовать команды вообще, а просто применить транзакционную логику к чему-то более простому.

...