3 unstable releases
0.1.1 | Sep 11, 2021 |
---|---|
0.1.0 | Jul 20, 2020 |
0.0.1 | Jul 29, 2019 |
#1764 in Database interfaces
140KB
3.5K
SLoC
Chekov
A
CQRS/ES
framework for building application in Rust
Table of Contents
Features
Postgres
EventStore backend- Dispatch
Command
toAggregate
- Generate
Event
fromAggregate
- Store and notify
Event
with subscriptions - Dispatch
Event
toEventHandler
Getting started
Choosing an EventStore backend
Chekov works only with Postgres
backend for now. The choice is easy to make!
But some more backends need to be implemented, see the related issue.
Defining Aggregates
An Aggregate is a struct that hold a domain state. Here's an example of a UserAggregate:
#[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(())
}
}
Defining Commands
You need to create a struct per command, any type of struct can implement Command
but we advise to use struct for a better readability.
A command can only produce (or not) one type of events and it targets a single Aggregate.
A command must have a single and unique identifier
that is used to route the command to the right target.
#[derive(Debug, Command)]
#[command(event = "UserCreated", aggregate = "User")]
struct CreateUser {
#[command(identifier)]
user_id: Uuid,
account_id: Uuid,
}
Defining Events
An Event
can be a struct
or an enum
.
#[derive(Event, Deserialize, Serialize)]
struct UserCreated {
user_id: Uuid,
account_id: Uuid,
}
Defining Saga
Not implemented yet
Dependencies
~19–31MB
~499K SLoC