Macro for defining Chronicle read models with embedded model-bound projections.
Use Chronicle.ReadModel in a struct module to define both the read model
shape and how Chronicle should project events into it. The projection
definition lives right next to the struct fields — no separate projection
module is needed.
Quick Example
defmodule MyApp.ReadModels.Account do
use Chronicle.ReadModel
defstruct account_id: nil, owner_name: nil, balance: 0, transaction_count: 0
from MyApp.Events.AccountOpened,
set: [
account_id: :event_source_id,
owner_name: :owner_name,
balance: :initial_balance
]
from MyApp.Events.FundsDeposited,
add: [balance: :amount, transaction_count: 1]
from MyApp.Events.FundsWithdrawn,
subtract: [balance: :amount],
add: [transaction_count: 1]
endProjection Macros
from/2
Maps properties from an event onto the read model.
from MyApp.Events.AccountOpened,
set: [account_id: :event_source_id, owner_name: :owner_name],
count: :transaction_countOptions:
:key— key expression identifying the model instance. Defaults to"$eventSourceId"when omitted.:parent_key— parent key for nested models:set— keyword list offield: expressionpairs to set directly:add— keyword list offield: expressionpairs to add to:subtract— keyword list offield: expressionpairs to subtract from:count— field atom to increment by 1 on each event occurrence
join/2
Joins a secondary event onto the model by a matching field.
join MyApp.Events.AccountVerified,
on: "accountId",
set: [verified: true]Options:
:on— (required) the field name in the event to join on:key— key expression (defaults to"$eventSourceId"):set,:add,:subtract— property mappings
removed_with/2
Removes the model instance when the given event occurs.
removed_with MyApp.Events.AccountClosed,
[]Options:
:key— key expression (defaults to"$eventSourceId"):parent_key— parent key for nested models
from_every/1
Applies property mappings on every event, regardless of type.
from_every set: [last_activity: "Occurred"]Options:
:set,:add,:subtract— property mappings applied to every event
Property Expressions
Values in set:, add:, and subtract: lists can be atoms, strings, or
literals:
- Use atoms for event fields (preferred):
:owner_name,:amount - Use
:event_source_idand:occurredfor built-in context values - Use strings for advanced Chronicle expressions when needed
- Use numbers and booleans as literal values
| Expression | Meaning |
|---|---|
:owner_name | The owner_name field from the event |
:event_source_id | The event source identifier |
:occurred | When the event was recorded |
1 | A literal integer constant |
"$add(amount, balance)" | An explicit Chronicle expression |
Registering with Chronicle.Client
{Chronicle.Client,
...
read_models: [MyApp.ReadModels.Account]}Introspection
MyApp.ReadModels.Account.__chronicle_read_model__(:id)
MyApp.ReadModels.Account.__chronicle_read_model__(:from)
MyApp.ReadModels.Account.__chronicle_read_model__(:join)
MyApp.ReadModels.Account.__chronicle_read_model__(:removed_with)
MyApp.ReadModels.Account.__chronicle_read_model__(:from_every)
MyApp.ReadModels.Account.__chronicle_read_model__(:has_projection?)
Summary
Functions
Declares how an event maps onto this read model.
Applies property mappings on every event, regardless of type.
Declares a join from a secondary event onto this read model.
Declares that this model is removed when the given event occurs.
Functions
Declares how an event maps onto this read model.
See the Chronicle.ReadModel module documentation for full options.
Applies property mappings on every event, regardless of type.
See the Chronicle.ReadModel module documentation for full options.
Declares a join from a secondary event onto this read model.
See the Chronicle.ReadModel module documentation for full options.
Declares that this model is removed when the given event occurs.
See the Chronicle.ReadModel module documentation for full options.