У меня есть довольно хорошая идея для тонкой гранулированной обработки команд 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
должно быть установлено для каждой команды, и вы должны ждать завершения каждой команды, прежде чем отправлять следующую.Это нехорошо.
У вас есть какие-нибудь идеи для этого?
Он должен загрузить агрегат один раз, а затем выполнить все команды.
И, возможно, даже есть некоторыеПоведение, подобное транзакции: применить все полученные события или ничего.