Reducers
Reducers provide a way to build read models by reducing a sequence of events into a single state. Unlike projections, which focus on transforming individual events into read models, reducers process collections of events together to compute derived state.
Key Concepts
Section titled “Key Concepts”A reducer is a specialized observer that:
- Processes multiple events together - Events are grouped by event source and passed to the reducer as a collection
- Computes derived state - The reducer method receives the current state and returns the new state after processing the events
- Maintains temporal consistency - All events for a given event source are processed in order
- Supports snapshots - The computed state can be retrieved at any point in the event stream
When to Use Reducers
Section titled “When to Use Reducers”Reducers are ideal when you need to:
- Aggregate data across multiple events - Calculate sums, averages, or other metrics from a series of events
- Build temporal models - Track how state changes over time
- Implement complex business logic - Process events together to derive insights that span multiple events
- Create snapshots - Capture the state of a read model at specific points in time
Basic Example
Section titled “Basic Example”public record AccountBalance(decimal Balance, DateTimeOffset LastUpdated);
public class AccountBalanceReducer : IReducerFor<AccountBalance>{ public AccountBalance OnDepositMade(DepositMade @event, AccountBalance? current, EventContext context) { var currentBalance = current?.Balance ?? 0m; return new AccountBalance(currentBalance + @event.Amount, context.Occurred); }
public AccountBalance OnWithdrawalMade(WithdrawalMade @event, AccountBalance? current, EventContext context) { var currentBalance = current?.Balance ?? 0m; return new AccountBalance(currentBalance - @event.Amount, context.Occurred); }}Topics
Section titled “Topics”- Getting Started - Learn how to create your first reducer
- Choose a read-model style - Compare reducers with model-bound and declarative projections
- Subscribe to External Event Stores - Configure outbox-to-inbox subscriptions for reducers
- Passive Reducers - Control when reducers actively observe events
- Event Processing - Understand how reducers process events
- Event Sequence - Specify which event sequence a reducer observes
- Filtering by appended event metadata - Limit reducers to specific tags, event source types, or event stream types
- Tagging Reducers - How to use tags with reducers
Reading Your Reducer-Based Read Models
Section titled “Reading Your Reducer-Based Read Models”Once you’ve defined a reducer, you can retrieve and observe the resulting read models using the IReadModels API:
- Getting a Single Instance - Retrieve a specific instance by key with strong consistency
- Getting a Collection of Instances - Retrieve all instances for reporting and analysis
- Getting Snapshots - Retrieve historical state snapshots grouped by correlation ID
- Watching Read Models - Observe real-time changes as events are applied