Event sourcing is a architectural pattern that captures and stores every state change within an application as a series of immutable events. Rather than only maintaining the current state of an entity, event sourcing use an append-only store to record the full series of actions led to the current state, allowing for the reconstruction of that state at any given point.
Conventional applications typically persist the end state without tracking the path that led to the current state. For instance, consider a service ticket record entity with evolving status
{Ticketid:1, comments:"VPN not working", status:'open'} - Initial State
After 2 days this ticket is assigned to someone
{Ticketid:1, comments:"VPN not working", status:'assigned'}
and it took 1 day for resolution and 1 more day to close (final state).
{Ticketid:1, comments:"VPN not working", status:'in-progress'}
{Ticketid:1, comments:"VPN not working", status:'closed'}
- end state only retained
This method loses the history of entity state changes, only retaining the final state. However, valuable information like “ticket was open for 2 days” or analytics to identify prolonged open tickets becomes inaccessible.
On the contrary, Event Sourcing retains all entity-changing events, constructing a comprehensive history of the service ticket’s evolution. This approach not only supports thorough analytics on all available data but also facilitates the creation of summarized snapshots by replaying events sequentially. This capability proves instrumental in reconstructing events and building projections.
TicketopenedEvent - {Ticketid:1, comments:"VPN not working", status:'opened'}
TicketAssignedEvent - {Ticketid:1, comments:"VPN not working", status:'assigned'}
TicketinprogressEvent - {Ticketid:1, comments:"VPN not working", status:'in-progress'}
TicketcloseEvent - {Ticketid:1, comments:"VPN not working", status:'closed'}
An example of event sourcing is activity logs in azure which provide insights into the operations performed on each Azure resource, The state is persisted as a series of immutable events.
Event stores serve as pivotal components in Event Sourcing architectures, providing reliable and durable storage solutions for recording and managing events. They empower applications to maintain a complete historical record, perform analytics, support recovery processes, and establish a robust foundation for building scalable and resilient systems. Notably, specialized databases like EventStoreDB cater specifically to Event Sourcing needs.
CQRS (Command Query Responsibility Segregation)
CQRS is a pattern that segregates the responsibilities of handling read and write operations within an application. Unlike the traditional CRUD (Create, Read, Update, Delete) approach, CQRS advocates for the separation of concerns between:
- Commands: Represent actions that modify the system’s state (e.g., creating, updating, or deleting data).
- Queries: Retrieve data without affecting the system’s state, offering a view of the data to the user.
The combination of Event Sourcing and CQRS allows services to operate independently, consuming events asynchronously to update read models without disrupting write-side operations.
Overcoming Challenges and Considerations
Implementing Event Sourcing and CQRS requires careful consideration, especially regarding event consistency across services, managing communication, and synchronizing events effectively.
Conclusion: Empowering Modern Architectures
Combination of Event Sourcing and CQRS fundamentally reshapes software architecture, offering resilience, scalability, and flexibility. In the dynamic landscape of software development, Event Sourcing and CQRS stand as pillars redefining how systems handle data, encouraging scalability and resilience.