A simple query

The command processing portion of a CQRS handles updates to the system but provides no insight into the current state. For this we will need one or more queries that read the events as they are committed. In the cqrs-es crate these events should implement the QueryProcessor trait.

For our first query, we will just print the aggregate instance ID, the sequence number and the event payload (pretty-serialized for readability).

struct SimpleLoggingQuery {}

impl QueryProcessor<BankAccount, BankAccountEvent> for SimpleLoggingQuery {
    fn dispatch(&self, aggregate_id: &str, events: Vec<EventEnvelope<BankAccount, BankAccountEvent>>) {
        for event in events {
            let payload = serde_json::to_string_pretty(&event.payload).unwrap();
            println!("{}-{}\n{}", aggregate_id, event.sequence, payload);

Note that the trait's sole method takes a vector of EventEnvelopes and this allows queries to have the full context surrounding the event. This is different from aggregates which receive only the event payload, thus any information needed for applying business rules and handling commands should be included in the event payload.