CQRS
What Is It
Command-Query Responsibility Segregation
- Separates
Command
(update) and Query
(read) operations to scale independently
CQRS is an interface design pattern, not a necessitation of separation of DB
Why Use It
With separation, you can optimize the system for read
and write
operations independently
- Write database is normalized, for consistency
- Read database is denormalized, for making the operation simple and fast (all reads become
SELECT * FROM
operation)
For read-heavy applications, it allows you to optimize the system for fast responses, without sacrificing consistency at the same time
Command vs Query
Command
operations are responsible for changing the state of the system
- also known as
state transition
Query
operations are responsible for returning the state of the system
- any data retrieval that beyond the need of
command
execution
Why use it
Separation allows for robust, scalable, and maintainable system
(Caveat) Divergence between Read and Write
When mutation is kicked off that is taking a while
- When the mutate is kicked off, there are two updates: state and read layer
Mutation being kicked off doesn't guarantee a timely read layer update
- when client requests the read layer before the mutation is complete, the client wont receive the new state
Workaround: Projection of
- Create a local update of successful mutation request
- Record of mutation request will be in queue with history
Event Sourcing
What is it
Pattern for storing data as events in append-only log
- by storing events, you also keep context of events
- e.g. you know an invoice was sent and for what reason from the same piece of information
- In other storage patterns, the business operation context is usually lost, or sometimes stored elsewhere
It is an alternative way to persist data
- contrast to state-oriented persistence
Event sourcing stores each state mutation as a separate record called event
- each
entity
mutation is persisted as an immutable event
An entity’s current state can be created by replaying all the events in order of occurrence
- we replay each mutation to get to current
state
- system information is sourced from the events
What is an Event
Event is a fact that took place within your business
- Every change made is an event and is appended to event log
Event represents a fact that took place in domain
- source of truth
- current state is derived from events
- they are immutable and represents business facts
- contains metadata such as timestamp, unique identifier of the subject
Why use Events
Source
Strong audit trail from immutability
- all state changes are kept
- possible to move forward and backwards
Debugging what-if is valuable
- existing data can be transformed to provide new insight
- business events can be tied back to their originating events
- can trace workflow from start to finish
Event Streams
- event streams are the source of truth for the domain object and contains full history of the changes
- stream should have a unique identifier representing the specific object
- each event has its own unique position within a stream
- position is represented with an incremental value
- this number can be used to define order of events and also be used to detect concurrency issues
Projections
- way of deriving current state of an entity by replaying the events
- projections can be done on-demand or asynchronously into a view/query model