Expand description
§Event Sourcing Framework
sourcerer
is a Rust framework for building event-sourced applications.
It provides the core traits and components to get started with event
sourcing, including aggregates, events, event stores, and repositories.
§Core Concepts
Aggregate
: A consistency boundary that processes commands and produces events.Event
: An immutable fact that represents a change in the state of an aggregate.EventStore
: A persistent store for events.SnapshotStore
: A persistent store for aggregate snapshots, used to optimize loading.Repository
: A high-level API for loading aggregates, handling commands, and saving events.
§Example
// 1. Define your aggregate, events, and commands.
use sourcerer::{Aggregate, AggregateId, Event, Snapshot};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum BankAccountEvent {
Opened { initial_balance: u64 },
Credited { amount: u64 },
Debited { amount: u64 },
}
impl Event for BankAccountEvent {
fn event_type(&self) -> &'static str {
match self {
BankAccountEvent::Opened { .. } => "Opened",
BankAccountEvent::Credited { .. } => "Credited",
BankAccountEvent::Debited { .. } => "Debited",
}
}
fn event_version(&self) -> u16 {
1
}
fn event_source(&self) -> &'static str { "urn:sourcerer:bank" }
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BankAccountSnapshot {
balance: u64,
}
impl Snapshot for BankAccountSnapshot {}
#[derive(Debug)]
pub enum BankAccountCommand {
Open { initial_balance: u64 },
Deposit { amount: u64 },
Withdraw { amount: u64 },
}
#[derive(Debug, Default)]
pub struct BankAccount {
id: Uuid,
balance: u64,
version: i64,
}
// 2. Implement the Aggregate trait.
#[sourcerer::async_trait]
impl Aggregate for BankAccount {
type Id = Uuid;
type Event = BankAccountEvent;
type Command = BankAccountCommand;
type Snapshot = BankAccountSnapshot;
type Error = std::convert::Infallible;
fn id(&self) -> &Self::Id {
&self.id
}
fn version(&self) -> i64 {
self.version
}
fn apply(&mut self, event: &Self::Event) {
match event {
BankAccountEvent::Opened { initial_balance } => {
self.balance = *initial_balance;
self.id = Uuid::new_v4();
}
BankAccountEvent::Credited { amount } => {
self.balance += *amount;
}
BankAccountEvent::Debited { amount } => {
self.balance -= *amount;
}
}
self.version += 1;
}
async fn handle(&self, command: Self::Command) -> Result<Vec<Self::Event>, Self::Error> {
// Business logic and validation here...
Ok(vec![])
}
fn from_snapshot(snapshot: Self::Snapshot) -> Self {
Self {
balance: snapshot.balance,
..Default::default()
}
}
fn snapshot(&self) -> Self::Snapshot {
BankAccountSnapshot {
balance: self.balance
}
}
}
// 3. Use the repository to interact with your aggregate.
use sourcerer::store::in_memory::InMemoryEventStore;
use sourcerer::store::in_memory_snapshot::InMemorySnapshotStore;
use sourcerer::repository::GenericRepository;
use std::sync::Arc;
async fn bank_account_example() {
let event_store = Arc::new(InMemoryEventStore::<BankAccount>::default());
let snapshot_store = Arc::new(InMemorySnapshotStore::<BankAccount>::default());
let repo = GenericRepository::new(event_store, Some(snapshot_store));
// ...
}
Re-exports§
pub use repository::Repository;
pub use snapshot::SnapshotStore;
pub use cloudevent::CloudEvent;
Modules§
- cloudevent
- CloudEvent conversion utilities.
- repository
- Provides a generic repository for interacting with aggregates.
- snapshot
- The snapshot module contains the traits and structs for creating and storing aggregate snapshots.
- store
- The store module contains the implementations of the event and snapshot stores.
- upcaster
- Defines the upcasting mechanism for handling event schema versioning.
Structs§
- Stored
Event - Represents a stored event, including metadata.
Enums§
- Error
- The error type for this crate.
Traits§
- Aggregate
- An aggregate is a consistency boundary. It is the fundamental building block of the domain model.
- Aggregate
Id - Uniquely identifies an aggregate instance.
- Event
- A marker trait for events.
- Event
Store - The trait for event stores.
- Snapshot
- A marker trait for snapshots.
Type Aliases§
- Result
- A specialized
Result
type for this crate’s operations.