3 个不稳定版本

0.1.1 2021 年 9 月 11 日
0.1.0 2020 年 7 月 20 日
0.0.1 2019 年 7 月 29 日

#8#事件存储

MIT/Apache

140KB
3.5K SLoC

Chekov

用于在 Rust 中构建应用的 CQRS/ES 框架

Actions Status Coverage Status dependency status Crates.io doc.rs doc-latest

目录


特性

  • Postgres 事件存储后端
  • Aggregate 分发 Command
  • Aggregate 生成 Event
  • 使用订阅存储和通知 Event
  • EventHandler 分发 Event

入门

选择事件存储后端

Chekov 目前仅支持 Postgres 后端。选择很简单!

但需要实现更多后端,请参阅相关问题

定义聚合

聚合是一个包含领域状态的 struct。以下是一个用户聚合的示例

#[derive(Default, Aggregate)]
#[aggregate(identity = "user")]
struct User {
    user_id: Option<Uuid>,
    account_id: Option<Uuid>,
}

/// Define an Executor for the `CreateUser` command
/// The result is a list of events in case of success
impl CommandExecutor<CreateUser> for User {
  fn execute(cmd: CreateUser, _state: &Self) -> Result<Vec<UserCreated>, CommandExecutorError> {
    Ok(vec![UserCreated {
      user_id: cmd.user_id,
      account_id: cmd.account_id,
    }])
  }
}

/// Define an Applier for the `UserCreated` event
/// Applier is a mutation action on the aggregate
#[chekov::applier]
impl EventApplier<UserCreated> for User {
  fn apply(&mut self, event: &UserCreated) -> Result<(), ApplyError> {
    self.user_id = Some(event.user_id);
    self.account_id = Some(event.account_id);

    Ok(())
  }
}

定义命令

您需要为每个命令创建一个 struct,任何类型的 struct 都可以实现 Command,但我们建议使用 struct 以提高可读性。

命令只能产生(或不产生)一种类型的事件,并针对单个聚合。命令必须有一个单一且唯一的 identifier,用于将命令路由到正确的目标。


#[derive(Debug, Command)]
#[command(event = "UserCreated", aggregate = "User")]
struct CreateUser {
    #[command(identifier)]
    user_id: Uuid,
    account_id: Uuid,
}

定义事件

一个 Event 可以是一个 struct 或一个 enum

#[derive(Event, Deserialize, Serialize)]
struct UserCreated {
    user_id: Uuid,
    account_id: Uuid,
}

定义 Saga

尚未实现

依赖项

~17–33MB
~480K SLoC