对于细粒度API命令处理我有一个非常好的主意。
我们的Web API应提供单个简单的update
端点,但您可以为其提供多个命令。像这样的东西:
POST /myAggregate/12345/update
[
{ command1Name: "command1Data" },
{ command2Name: "command2Data" },
{ command3Name: "command3Data" }
]
在Axon中,这似乎很难处理。特别是与@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注入时,它变得非常难。
我的第二个想法是简单地在循环中调用commandGateway.send
。但是这会爆发,因为必须为每个命令设置@TargetAggragateVersion
,并且在发送下一个命令之前必须等待每个命令完成。那不好。
你有什么想法吗?
它应该加载一次聚合,然后运行所有命令。
甚至可能有一些类似事务的行为:应用所有结果事件,或者没有。
我认为你最好立即解决这个问题,而不需要等到你添加到Axon Framework的问题跟踪器的issue,就是添加一个External Command Handler。
外部命令处理程序只是一个带有@CommandHandler
注释函数的常规组件。该方法将处理您的UpdateWrapperCommand
并知道为包含它的每个命令有效负载发出单独命令的工作。
然而,正如您所建议的那样,Aggregate的加载优化实际上与实现批处理命令解决方案有关。虽然这在框架中绝对可行,但此功能尚未到位。我建议你继续跟踪你创建的issue以跟踪它的进展。
希望这可以帮助你解决本杰明!
如果事务意味着全部或全部,那么可能每个命令的边界都没有很好地建模。
如果不了解域名,我会说选项是:
1仅将所有命令包装在一个并应用于一个句柄 - 所有聚合。
2单独应用所有命令,如果出现任何故障,则应用补偿操作。
3根本不使用命令,只需将事务逻辑应用于更简单的事情。