在发布事件之前如何确保聚合存在?

How do I make sure an aggregate exists before publishing an event?

我正在查看 Wolkenkit API ... 并不能 100% 清楚如何知道哪些命令需要聚合 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 检查?

@goloroden in the wolkenkit slack

于 2018 年 6 月 8 日回答

我会尽力向您解释:如果您想要一个 new 聚合,则省略 ID。因此,例如,继续使用聊天示例,当您想发送一条新消息时:

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

相反,如果您想编辑 现有 消息,例如想要点赞,就得提供留言ID:

const messageId = '...';

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

在每个命令中,您可能希望检查它是否仅适用于新聚合(我们称之为 构造函数命令)或仅适用于现有聚合。检查这一点的最简单方法是使用聚合的 exists 函数,returns 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 之前,您必须使用 [=20] 的 2.0 版本=].