Getting events
Event sequences support multiple ways of reading events depending on your needs. The IEventSequence APIs (and the specialized IEventLog) cover common patterns such as:
- Reading events from a sequence in order
- Reading events for a specific event source
- Reading a range of events based on sequence numbers
- Reading a fixed number of events from the tail
Use the client APIs to select the pattern that best matches your scenario, such as replaying state, building read models, or auditing changes.
Examples
Section titled “Examples”Read events for a single event source
Section titled “Read events for a single event source”using Cratis.Chronicle.Events;using Cratis.Chronicle.EventSequences;using System.Collections.Immutable;
[EventType]public record GettingEventsOrderPlaced(string OrderId, decimal Total);
[EventType]public record GettingEventsOrderCancelled(string OrderId, string Reason);
public class GettingEventsOrderHistoryReader(IEventLog eventLog){ public async Task<IImmutableList<AppendedEvent>> GetOrderEvents(EventSourceId orderId) { // Filters the timeline to only the order events you care about. var eventTypes = new[] { typeof(GettingEventsOrderPlaced).GetEventType(), typeof(GettingEventsOrderCancelled).GetEventType() };
return await eventLog.GetForEventSourceIdAndEventTypes(orderId, eventTypes); }}Kotlin does not support this workflow yet.Java does not support this workflow yet.defmodule MyApp.Events.GettingEventsOrderPlaced do use Chronicle.Events.EventType, id: "getting-events-order-placed"
defstruct [:order_id, :total]end
defmodule MyApp.Events.GettingEventsOrderCancelled do use Chronicle.Events.EventType, id: "getting-events-order-cancelled"
defstruct [:order_id, :reason]end
defmodule MyApp.GettingEventsOrderHistoryReader do alias Chronicle.EventSequences.EventLog alias MyApp.Events.{GettingEventsOrderCancelled, GettingEventsOrderPlaced}
def get_order_events(order_id) do # Filters the timeline to only the order events you care about. EventLog.get_for_event_source(order_id, event_types: [GettingEventsOrderPlaced, GettingEventsOrderCancelled] ) endendTypeScript does not support this workflow yet.Kotlin, Java, and TypeScript don’t currently expose a way to read raw events back for an event source — their public event sequence APIs only support appending and checking for existence.
Read from a checkpoint
Section titled “Read from a checkpoint”using Cratis.Chronicle.Events;using Cratis.Chronicle.EventSequences;using System.Collections.Immutable;
public class GettingEventsReplayEvents(IEventLog eventLog){ public async Task<IImmutableList<AppendedEvent>> ReadFrom(EventSequenceNumber sequenceNumber) { // Replays from a known checkpoint to rebuild projections or read models. return await eventLog.GetFromSequenceNumber(sequenceNumber); }}This is currently a C#-only capability — no other client exposes a way to resume reading from an arbitrary sequence number.
Read the last events in a sequence
Section titled “Read the last events in a sequence”using Cratis.Chronicle.Events;using Cratis.Chronicle.EventSequences;using System.Collections.Immutable;using System.Linq;
public class GettingEventsTailReader(IEventLog eventLog){ public async Task<IImmutableList<AppendedEvent>> ReadLast(int count) { // Reads from the computed start and trims in memory to the requested count. var tail = await eventLog.GetTailSequenceNumber(); var start = tail.IsActualValue && tail.Value >= (ulong)count ? tail - (count - 1) : EventSequenceNumber.First;
var events = await eventLog.GetFromSequenceNumber(start); return events.TakeLast(count).ToImmutableList(); }}Reading the tail this way also relies on resuming from a sequence number, so it’s currently C#-only too. Kotlin, Java, and TypeScript can still get the tail sequence number (see Getting state), just not the events at it.