如何在发布活动之前确保聚合存在?

时间:2018-06-08 08:22:11

标签: node.js domain-driven-design cqrs event-sourcing wolkenkit

我正在查看Wolkenkit API ...并且不清楚如何知道哪些命令需要聚合ID而哪些命令不需要。

据我所知,客户端api提供类似这样的内容

app.accounting.invoice().issue({
  amount: 1000
});

这对于创建新的invoice很好,但是不应该运行以下打算更新存在的内容

app.accounting.invoice().update({
  amount: 10
});

我认为这个检查应该进入命令功能,但我该怎么写呢?

const commands = {
  update (invoice, command, mark) {
    const canInvoiceBeUpdated = // ...

    if (!canInvoiceBeUpdated) {
      return mark.asRejected('...');
    }

    // ... update invoice

    mark.asDone();
  }
};

canInvoiceBeUpdated检查的内容是什么?

1 个答案:

答案 0 :(得分:3)

@goloroden

wolkenkit slack已回复2018-06-08

我会尝试向您解释:如果您想要 new 聚合,则省略ID。因此,例如,要坚持使用聊天示例,当您要发送新消息时:

app.communication.message().send({ /* ... */ });

相反,如果您要编辑现有消息,例如喜欢它,那么你必须提供消息的ID:

const messageId = '...';

app.communication.message(messageId).like({ /* ... */ });

在每个命令中,您可能希望检查它是否仅适用于新聚合(我们称之为构造函数命令)或仅适用于现有聚合。检查此问题的最简单方法是使用聚合的exists函数,该函数为新聚合返回true,否则返回false。因此,在命令内部,您可以执行以下操作:

const commands = {
  send (message, command, mark) {
    if (!message.exists()) {
      return mark.asRejected('Aggregate does not exist yet.');
    }

    // ...

    mark.asDone();
  }
};

如果您不想每次都手动执行此操作,您也可以使用中间件,例如https://github.com/thenativeweb/wolkenkit-command-tools ...然后前面的示例归结为:

const { only } = require('wolkenkit-command-tools');

// ...

const commands = {
  send: [
    only.ifExists(),
    (message, command, mark) {
      // ...

      mark.asDone();
    }
  ]
};

请注意,此中间件模块的当前版本为3.0,但在wolkenkit 2.0发布之前,您必须使用2.0版本wolkenkit-command-tools