Skip to main content

Writing and Deploying Aggregates

In Thalo, aggregates are the central part of the event-sourcing model. This section guides you through defining, implementing, compiling, and running aggregates.

Defining an Aggregate

An aggregate in Thalo is a Rust struct that represents a collection of objects with a shared lifecycle. To define an aggregate:

use thalo::{Aggregate, export_aggregate};

export_aggregate!(MyAggregate);
pub struct MyAggregate {
// fields go here
}
impl Aggregate for MyAggregate {
// implementation details
}

The export_aggregate! macro makes the aggregate available to the Thalo runtime.

Implementing Commands and Events

Commands

Commands are actions that modify the state of an aggregate. They are defined using an enum and the Command derive macro, and must also implement Deserialize:

use thalo::Command;
use serde::Deserialize;

#[derive(Command, Deserialize)]
pub enum MyCommand {
// command variants
}

Commands can be defined as inline or external:

Inline Commands

Inline commands are defined in a single enum with one implementation of Handle:

// Inline commands
#[derive(Command, Deserialize)]
pub enum MyCommand {
Command1 { foo: String },
Command2 { bar: String },
}

impl Handle<MyCommand> for MyAggregate { ... }

External Commands

External commands use one struct per command, where each struct implements Handle:

// External commands
#[derive(Command, Deserialize)]
pub enum MyCommand {
Command1(Command1),
Command2(Command2),
}

#[derive(Deserialize)]
pub struct Command1 { foo: String }
impl Handle<Command1> for MyAggregate { ... }

#[derive(Deserialize)]
pub struct Command2 { bar: String }
impl Handle<Command2> for MyAggregate { ... }

Events

Events represent the result of executing commands. They are immutable and defined using an enum and the Event derive macro, along with Serialize and Deserialize:

use thalo::Event;

#[derive(Event)]
pub enum MyEvent {
// Event variants
}

Each variant must implement Apply, which is how the aggregate state is updated.

Compiling Aggregates to Wasm

To compile your aggregate to WebAssembly (wasm), use the Thalo CLI:

thalo build my_aggregate -o ./modules

This command compiles the aggregate and prepares it for execution in the Thalo runtime environment.

Loading and Running Aggregates in Thalo

Once compiled, Thalo automatically loads all wasm modules from the specified directory. Start the Thalo runtime with:

thalo-runtime
INFO: loaded module from file file="modules/my_aggregate.wasm"

Your aggregate is now running and ready to handle commands and events.