Expand description
§Projection Module
Three-trait architecture for building read models from event streams:
Projector— stateless event handler (the “machine”). Contains the pure logic for transforming events into read model writes.Projection— composed read model unit (the “output”). Ties a projector to its storage backend.ReadModelStore— persistence layer for projections. Backend-agnostic storage (defined inread_model_storemodule).
§Design Principles
- Separation of concerns: Handler logic (projector) is separate from storage (read model store) and orchestration (projection engine)
- Stateless projectors: Projectors take
&self, not&mut self. All mutable state lives in theReadModelStorevia interior mutability. - Rebuildable: Projections can be rebuilt from scratch by replaying events
- Idempotent: Handling the same event multiple times should be safe
- Composable: One projector per read model concern; swap backends freely
§Example
ⓘ
use arc_core::projection::{Projector, Projection, ProjectionUnit, ProjectionEngine};
use arc_core::read_model_store::{ReadModelStore, InMemoryReadModelStore};
use arc_core::event::Event;
use std::sync::Arc;
struct UserListProjector;
#[async_trait]
impl Projector for UserListProjector {
fn name(&self) -> &str { "UserList" }
fn handles(&self) -> Vec<String> {
vec!["UserCreated".to_string(), "ProfileUpdated".to_string()]
}
async fn apply(&self, event: &Event, store: &dyn ReadModelStore) -> ProjectionResult<()> {
match event.event_type.as_str() {
"UserCreated" => {
store.upsert(Upsert::new("users_view", &event.aggregate_id, event.payload.clone())).await
.map_err(|e| ProjectionError::handle_failed("UserList", &event.event_type, &event.event_id.to_string(), e.to_string()))?;
}
_ => {}
}
Ok(())
}
}
// Compose: projector + store = projection
let store = Arc::new(InMemoryReadModelStore::new());
let projection = ProjectionUnit::new(Box::new(UserListProjector), store, "users_view");
// Register with engine
let mut engine = ProjectionEngine::new(event_store);
engine.register(Box::new(projection));
engine.process(&event).await?;Structs§
- Projection
Engine - Engine for managing multiple projections.
- Projection
Engine Handler - Adapter that lets a
ProjectionEnginesubscribe to anEventBus. Wraps the engine in anEventHandlerthat routes every relevant event throughProjectionEngine::process. The engine stays accessible from outside (e.g. forrebuild_all) via the sameArc. - Projection
Unit - Standard composition of a
Projectorand aReadModelStore.
Enums§
- Projection
Error - Errors that can occur during projection operations.
Traits§
- Projection
- A projection is the composed unit of a projector + its read model store.
- Projector
- A projector contains the pure event-handling logic for building a read model.
Type Aliases§
- Projection
Result - Result type for projection operations.