๐จ CQRS & Event-Driven Thinking: Let's Learn from ZERO!
These are important backend architecture concepts, especially with FastAPI, PostgreSQL, SQLAlchemy, repositories, services and a social media app. We'll cover:
- ๐ What Command-Query Separation (CQS) means
- ๐งฉ What CQRS is and how it differs from CQS
- โ๏ธ Commands vs queries
- ๐ฃ What domain events are
- ๐ How event-driven architecture works
- ๐ข Real examples using an Instagram-like app
- โ Advantages, disadvantages, use cases and interview questions
We'll start simple and gradually move towards real backend code. ๐
1. ๐ค First, Understand the Problem
You're building an Instagram-like app. A user can:
- Create a post
- Like a post
- Comment on a post
- Follow another user
- View their home feed
- Search for posts
- View someone's profile
All of these touch the database. But are they all doing the same kind of work? No! There are two fundamentally different kinds of operations:
| Kind | Examples | Effect |
|---|---|---|
| โ๏ธ Writing / changing data | Create a post, like a post, delete a comment, follow a user | Changes the database |
| ๐ Reading / retrieving data | Get all posts, view comments, get a profile, search posts | Retrieves information without changing it |
This distinction is the foundation of Command-Query Separation.
2. ๐ Command-Query Separation (CQS)
- Command: an instruction to perform an action
- Query: a request to retrieve information
- Separation: keeping these two responsibilities apart
๐ Command-Query Separation means separating operations that change data from operations that only read data. A command changes the state of the system. A query returns information but does not change the state.
State means the current stored condition of your application. For example, a post:
{
"id": 101,
"caption": "My first post",
"likes_count": 10
}
Its current state: the post has 10 likes.
2.1 โ๏ธ Command example: like a post
The frontend sends POST /posts/101/like. The backend:
- Identifies the logged-in user
- Checks the post exists
- Checks the user hasn't already liked it
- Inserts a like record
- Updates the like count, if your design stores one
Before: { "id": 101, "likes_count": 10 }
After: { "id": 101, "likes_count": 11 }
The database state changed, so this is a Command.
2.2 ๐ Query example: get post details
The frontend sends GET /posts/101. The backend finds the post, retrieves its caption, author and like count, and returns:
{
"id": 101,
"caption": "My first post",
"likes_count": 11
}
Did we change anything? No. So this is a Query.
2.3 ๐ Visual comparison
| โ๏ธ COMMAND (write) | ๐ QUERY (read) |
|---|---|
| Changes application state | Does not change application state |
| Create, Update, Delete, Like | Get, List, Search, Retrieve |
๐ง Command = change something. Query = ask for something.
2.4 ๐ More examples
| Operation | Type | Reason |
|---|---|---|
| Create post | Command | Inserts data |
| Edit caption | Command | Updates data |
| Delete post | Command | Removes data |
| Like post | Command | Changes like state |
| Follow user | Command | Changes follow relationship |
| Get profile | Query | Reads data |
| Get feed | Query | Retrieves posts |
| Search users | Query | Reads matching records |
| Get comments | Query | Retrieves comments |
๐ A query can have internal work such as logging or caching, but its purpose must not be to change the business data being queried.
3. ๐คท Why Do We Need CQS?
Imagine this function:
def get_post(post_id):
post = database.get_post(post_id)
if post.likes_count == 0:
post.likes_count = 1
database.save(post)
return post
What's wrong? It's named get_post(), so we expect it to retrieve a post. But it also changes the database! Someone calling get_post() might accidentally modify application data. A better design:
def get_post(post_id):
return database.get_post(post_id)
def like_post(post_id):
post = database.get_post(post_id)
post.likes_count += 1
database.save(post)
return post
-
get_post()โ Query -
like_post()โ Command
โ Main benefit: your code becomes easier to understand, maintain, test and debug.
4. ๐งฉ What is CQRS?
๐ CQRS = Command Query Responsibility Segregation. It's an architectural pattern based on the same idea as CQS.
- CQS is a principle about separating read and write operations
- CQRS takes that further by letting the read and write sides have different models, responsibilities, and sometimes different data stores
4.1 ๐๏ธ Traditional architecture
Frontend (React)
โผ
Backend API (FastAPI)
โผ
PostgreSQL Database โ same database for reading and writing
Writing means insert/update/delete, reading means select. This is completely valid and works very well for many apps. But if your app becomes extremely popular (1 million users, 10 million posts, millions of feed requests, thousands of new posts and likes every minute) the database must handle heavy reads and writes together. That's where CQRS can become useful.
4.2 ๐งฑ CQRS architecture
Frontend (React)
โโโโโโโโโโดโโโโโโโโโ
Command Query
(write request) (read request)
โผ โผ
Command Handler Query Handler
(validates and processes (processes read
writes) requests)
โผ โผ
Write Model Read Model
(PostgreSQL) (optimized for retrieval)
(Conceptual. Read and write models may use the same database or different ones.)
Write side: handles commands, validates business rules, changes application state, saves data.
Read side: handles queries, retrieves information, returns data in a format suitable for the frontend, and can be optimized for fast reads.
4.3 ๐๏ธ Does CQRS require two databases?
No! A very important interview question. There are two common implementations:
Option A: same database, separate models. Command and query logic are separate, but they share the same underlying database. For example, the command handler uses the SQLAlchemy ORM to create a post, while the query handler uses optimized SQL to retrieve posts.
Option B: separate read and write databases. Write model: PostgreSQL. Read model: Redis, Elasticsearch, or a separate PostgreSQL database. The read database may hold precomputed or denormalized information for faster retrieval. Use this when you need independent scaling or specialized read storage.
4.4 ๐ What is a Read Model?
๐ A read model is a representation of data designed specifically for reading.
Suppose your database has:
users:
| id | username |
|---|---|
| 1 | deepika |
| 2 | arjun |
posts:
| id | user_id | caption |
|---|---|---|
| 101 | 1 | My first post |
| 102 | 2 | Weekend vibes |
likes:
| id | post_id | user_id |
|---|---|---|
| 1 | 101 | 2 |
| 2 | 101 | 1 |
To display a feed you may need to join several tables and count likes. Your frontend wants:
[
{
"post_id": 101,
"username": "deepika",
"caption": "My first post",
"likes_count": 2
}
]
This combined structure is a read model. It's shaped for the frontend's needs rather than matching your original tables. Instead of repeating expensive joins and calculations on every feed request, you can maintain a read-optimized representation, for example a precomputed like count or a denormalized feed projection.
4.5 โ๏ธ What is a Write Model?
The write model is the representation used to perform and enforce changes. When a user likes a post, the write side must ensure the post exists, the user exists, the user hasn't already liked it, and the like is stored correctly. It maintains business rules and data integrity.
| Write Model | Read Model |
|---|---|
| Handles changes | Handles retrieval |
| Processes commands | Processes queries |
| Enforces business rules | Optimizes presentation |
| Focuses on consistency | Focuses on efficient reads |
4.6 ๐ When should we use CQRS?
- Read-heavy apps: millions of users frequently retrieve information
- Complex queries: many joins, aggregations and calculations
- Different scaling needs: read and write traffic scale independently
- Different data representations: the frontend needs data structured differently from the normalized write database
- Complex business workflows: many operations and rules affect the same domain
When should you avoid it? For a small CRUD app, CQRS adds unnecessary complexity. You'd maintain two models, command handlers, query handlers, event processing, synchronization, and error handling for failed projections. A normal layered FastAPI app is often enough.
โ ๏ธ CQRS is an architectural choice, not a requirement for every backend.
5. ๐ฃ What is Event-Driven Thinking?
A user creates a post and the backend saves it. After that, several other things may need to happen:
- The post should appear in the user's feed
- Followers may receive notifications
- The profile's post count may increase
- Analytics may record the new post
- An image-processing service may generate thumbnails
Should the post-creation function directly perform all of these? It could, but if the notification service is slow or temporarily unavailable, should the user wait for it before their request finishes? Probably not. That's where event-driven thinking helps.
5.1 ๐ What is an Event?
๐ An event represents something that has already happened.
Examples: UserRegistered, PostCreated, PostLiked, CommentAdded, UserFollowed, OrderPlaced, PaymentCompleted.
Notice the past tense. An event is a completed fact. PostCreated means a post has already been created. It doesn't mean someone is requesting creation. That distinction is extremely important.
5.2 โ๏ธ Command vs Event
| โ๏ธ Command | ๐ฃ Event |
|---|---|
CreatePost: "Please create a new post."
|
PostCreated: "A new post has been successfully created."
|
| An instruction that requests something happen | A fact that announces something happened |
| Command | Event |
|---|---|
RegisterUser |
UserRegistered |
CreatePost |
PostCreated |
LikePost |
PostLiked |
AddComment |
CommentAdded |
FollowUser |
UserFollowed |
PlaceOrder |
OrderPlaced |
MakePayment |
PaymentCompleted |
๐ง Command = request to do something. Event = notification that something has happened.
5.3 ๐ How does event-driven architecture work?
1. User creates a post โ React frontend
โผ
2. CreatePost command โ backend receives the instruction
โผ
3. Command Handler โ validates and saves the post
โผ
4. PostCreated event โ a fact is published after successful creation
โผ
5. Event Bus / Event Broker โ distributes the event to interested consumers
โโโ ๐ Notifications
โโโ ๐ผ๏ธ Media
โโโ ๐ Analytics
One event can trigger several independent reactions.
A. Event Producer: the component that creates and publishes an event. Here, the post creation service saves the post and publishes PostCreated.
B. Event: carries information about what happened:
{
"event_id": "evt_001",
"event_type": "PostCreated",
"post_id": 101,
"user_id": 1,
"created_at": "2026-11-12T10:30:00Z"
}
(An illustrative payload.) It tells other components which event occurred, which post was created, which user created it and when. An event should contain enough information for consumers to do their work, without unnecessarily exposing private data.
C. Event Bus / Event Broker: a communication system that receives events from producers and delivers them to interested consumers. Technologies include RabbitMQ, Apache Kafka, Redis Streams, AWS EventBridge. For a small app you can even use a simple in-process event dispatcher with no broker at all.
D. Event Consumer: a component that receives and reacts to an event. When PostCreated occurs, the notification consumer sends notifications, the analytics consumer records the activity, and the media consumer processes images. Each has its own responsibility.
๐ The event producer doesn't need to know the internal implementation of every consumer, which reduces coupling.
6. ๐ท๏ธ What are Domain Events?
๐ A domain event is an event that represents something meaningful that happened in the application's business domain.
A domain is the business area or problem your app is built to handle:
| Application | Domain |
|---|---|
| Instagram-like app | Social networking |
| Banking app | Banking |
| E-commerce app | Online shopping |
| Hospital app | Healthcare management |
| Food delivery app | Food ordering and delivery |
In a social media app the domain includes users, posts, comments, likes, follows and notifications. When a user follows another user and the operation succeeds, we can represent that important business fact as the domain event UserFollowed.
6.1 ๐ Examples of domain events
Social media:
| Domain Event | Meaning |
|---|---|
UserRegistered |
A new account was registered |
ProfileUpdated |
A profile was updated |
PostCreated |
A new post was created |
PostDeleted |
A post was deleted |
PostLiked |
A user liked a post |
CommentAdded |
A comment was added |
UserFollowed |
A user followed another user |
UserUnfollowed |
A user unfollowed another user |
E-commerce:
| Domain Event | Meaning |
|---|---|
ProductAddedToCart |
A product was added |
OrderPlaced |
An order was placed |
PaymentCompleted |
Payment succeeded |
OrderCancelled |
An order was cancelled |
ItemShipped |
An item was shipped |
6.2 โ๏ธ Domain event vs command vs query
| Concept | Meaning | Example |
|---|---|---|
| Command | Request to perform an action | LikePost |
| Query | Request to retrieve data | GetPost |
| Domain Event | Something meaningful happened | PostLiked |
A complete sequence:
- A user clicks Like
- The backend receives
LikePost - The backend checks the rules
- The backend saves the like
- The backend generates
PostLiked - Other components react to
PostLiked
LikePost (Command)
โผ
Business logic + database write
โผ
PostLiked (Domain Event)
โผ
Event consumers: ๐ Notification ยท ๐ Analytics
The command asks the system to do something. The event records that the system successfully did it.
6.3 ๐ค Are domain events always published to Kafka or RabbitMQ?
No. A domain event is a concept. It can exist entirely inside your application. For example, your Python app can create a PostCreated event object and pass it to an internal event dispatcher. You only need Kafka, RabbitMQ or another broker when your architecture requires the capabilities they provide.
7. โณ Synchronous vs Asynchronous Event Processing
7.1 ๐ข Synchronous processing
The caller waits for the operation to finish before continuing:
def create_post(post_data):
post = save_post(post_data)
send_notification(post)
update_analytics(post)
return post
- Save post
- Wait for notification
- Wait for analytics
- Return response
If notification takes 3 seconds and analytics takes 2, the request may take about 5 seconds longer than the database save itself. The user waits for all of it.
7.2 ๐ Asynchronous event processing
def create_post(post_data):
post = save_post(post_data)
publish_event(
"PostCreated",
{"post_id": post.id},
)
return post
Event consumers process their tasks independently (notifications, analytics, image processing), and the request doesn't have to wait for them.
Synchronous: Save post โ Send notification โ Update analytics โ Return response (after all)
Asynchronous: Save post โ Publish event โ Return response
โโโ Notification
โโโ Analytics (processed independently)
๐ Asynchronous doesn't automatically mean a separate server or message broker. Python background tasks, queues and distributed brokers are different implementation options. For reliable processing across services, a durable message broker is often preferable to an in-memory background task.
7.3 ๐ What is Eventual Consistency?
A user creates a post. The write database saves it immediately, but your separate read database or feed projection may take a moment to receive and process PostCreated. For a brief moment the write database says the post exists, while the read database hasn't caught up. After the event is processed, both agree.
Time T1 (write completed) Write DB: Post exists (ID 101) Read DB: Post not yet visible
Time T2 (event processed) Write DB: Post exists (ID 101) Read DB: Post exists (ID 101)
๐ Eventual consistency: the system may temporarily show slightly outdated information, but if processing succeeds and continues, the read side eventually catches up.
For analytics, recommendation updates and notification delivery, a small delay is often acceptable. But for critical operations such as checking an account balance before a withdrawal, you generally need strong consistency at the point of decision.
8. ๐ฅ What Happens If Event Processing Fails?
Your app saves a post in PostgreSQL, then tries to publish PostCreated to RabbitMQ, but RabbitMQ is temporarily down. The post exists, yet the event was never published, so the notification service may never learn about it. That's a reliability problem. One important solution is the Transactional Outbox Pattern.
8.1 ๐ค Transactional Outbox Pattern
Instead of saving business data and publishing the event as two unrelated operations, save both the business data and an event record in the same database transaction.
posts:
| id | caption |
|---|---|
| 101 | My first post |
outbox_events:
| id | event_type | payload | published |
|---|---|---|---|
| 1 | PostCreated | post_id:101 |
false |
The process:
- Start a database transaction
- Insert the post
- Insert the
PostCreatedevent into the outbox table - Commit the transaction
- A background worker reads unpublished events
- The worker publishes them to the broker
- The worker marks them as published after successful delivery
BEGIN TRANSACTION
Insert post
Insert event
COMMIT โ both records saved together
โผ
Background Worker
โผ
Message Broker
Even if the broker is down, the event remains safely stored in PostgreSQL and can be published later.
โ ๏ธ Caveat: a worker can publish an event and crash before marking it as published, so the event may be delivered again. That's why consumers should be idempotent.
8.2 ๐ What is Idempotency?
๐ Idempotency means performing the same operation multiple times produces the same intended result as performing it once.
Suppose PostLiked is delivered twice. If your consumer blindly increments the like count each time, the count goes up twice. That's wrong. A safer design:
- Store processed event IDs
- Check whether an event was already processed
- If yes, skip it
- If not, process it and record its ID
9. โก How Does This Fit into FastAPI Architecture?
9.1 ๐ฅ Traditional layered architecture
For POST /posts:
frontend โ FastAPI Router โ Post Service โ Post Repository โ PostgreSQL
The router receives the request, the service implements business logic, and the repository handles database operations.
9.2 ๐งฉ Introducing CQRS
Separate the write and read responsibilities:
FastAPI
โโโโโโโโโโโดโโโโโโโโโโ
Command Router Query Router
โผ โผ
Command Handler Query Handler
โผ โผ
Write Repository Read Repository
โผ โผ
Database Database
Command handler:
class CreatePostCommand:
def __init__(self, user_id, caption):
self.user_id = user_id
self.caption = caption
def handle_create_post(command, repository):
post = repository.create(
user_id=command.user_id,
caption=command.caption,
)
return post
Query handler:
def handle_get_post(post_id, repository):
return repository.get_by_id(post_id)
(Simplified examples, not a complete production implementation.)
-
CreatePostCommandrepresents the instruction -
handle_create_post()processes the write -
handle_get_post()retrieves information
You can have separate command and query handlers even when both use the same SQLAlchemy session and PostgreSQL database.
9.3 ๐ฃ Introducing domain events
Extend the command handler:
def handle_create_post(command, repository, event_publisher):
post = repository.create(
user_id=command.user_id,
caption=command.caption,
)
event = {
"event_type": "PostCreated",
"post_id": post.id,
"user_id": command.user_id,
}
event_publisher.publish(event)
return post
CreatePost Command
โผ
Command Handler
โผ
Post Repository
โผ
PostgreSQL
โผ
PostCreated Event
โผ
Event Publisher
โผ
Event Consumers
โ ๏ธ For production reliability, you'd normally use the transactional outbox pattern instead of relying on a direct database-write-then-publish sequence.
10. ๐ Domain Events vs Integration Events
Related, but not identical.
Domain event: represents an important business fact inside a particular domain. It might be used by your app's internal business logic.
PostCreated(
post_id=101,
user_id=1,
)
Integration event: communicates something that happened to another system or independent service. It might be published through RabbitMQ or Kafka so another service can consume it.
{
"event_type": "PostCreated",
"post_id": 101,
"user_id": 1
}
| Domain Event | Integration Event |
|---|---|
| Internal to a domain | Shared across service boundaries |
| Represents business facts | Communicates business facts to other systems |
| Can be an internal Python object | Usually has a serialized message format |
| May never leave the application | Intended for external consumers |
A domain event can lead to an integration event, but not every domain event needs to be published externally.
11. โ๏ธ CQRS vs Event-Driven Architecture vs Event Sourcing
These three are often discussed together but solve different problems.
๐
ฐ๏ธ CQRS. Separate reading and writing responsibilities. CreatePost โ command, GetPost โ query. Focus: how your app handles reads and writes.
๐
ฑ๏ธ Event-Driven Architecture (EDA). Components communicate and react to events. PostCreated triggers notifications, analytics and image processing. Focus: how components communicate and respond to changes.
๐
ฒ Event Sourcing. A different concept. Don't confuse it with EDA. Normally your database stores the current state:
{
"account_id": 1,
"balance": 700
}
With event sourcing, instead of treating current state as the primary record, you store the sequence of events that produced it:
| Event | Amount |
|---|---|
AccountCreated |
0 |
MoneyDeposited |
+1000 |
MoneyWithdrawn |
-200 |
MoneyWithdrawn |
-100 |
The balance is calculated by replaying the events: 1000 โ 200 โ 100 = 700.
Traditional database: Current balance = โน700
Event sourcing: Deposited โน1,000 โ Withdrawn โน200 โ Withdrawn โน100 โ Current balance = โน700
Why use it? Complete history of changes, ability to reconstruct previous states, audit trails, and understanding exactly how a value changed over time.
But it adds complexity: event versioning, event replay, data migration, handling duplicate events and maintaining projections. You don't need event sourcing just because you're using events.
| Concept | Main responsibility |
|---|---|
| CQS | Separate reads and writes at the operation level |
| CQRS | Separate read and write models/responsibilities |
| Event-Driven Architecture | Communicate through events |
| Domain Events | Represent important business facts |
| Event Sourcing | Store state changes as an event history |
๐ฏ Very important: CQRS and EDA can be used together, but neither requires Event Sourcing.
12. ๐งต Practical Example: A Social Media App
Imagine Deepika likes Arjun's post.
Step 1: the frontend sends a command
POST /posts/101/like
Authorization: Bearer access_token
Step 2: FastAPI receives the request
@router.post("/posts/{post_id}/like")
async def like_post(
post_id: int,
current_user=Depends(get_current_user),
):
return await service.like_post(
post_id,
current_user.id,
)
Step 3: the service processes the command. It checks the post exists, checks whether the user already liked it, applies business rules, and creates the like record.
Step 4: the database saves the change
likes
id | post_id | user_id
1 | 101 | 1
Step 5: a domain event is generated
{
"event_type": "PostLiked",
"post_id": 101,
"user_id": 1
}
Step 6: event consumers react. The notification service informs the post owner, analytics records the interaction, and a read projection updates the like count, if the app maintains one.
Step 7: the user retrieves the post
GET /posts/101
This is a Query. The query handler returns:
{
"post_id": 101,
"caption": "My first post",
"likes_count": 15,
"liked_by_me": true
}
This one example demonstrates CQS, CQRS, domain events, event-driven architecture, event consumers and eventual consistency.
๐ If
liked_by_memust update immediately, read it from the authoritative write-side data, or otherwise ensure the response reflects the successful write. Don't assume an asynchronously updated read model is immediately current.
13. ๐ Important Terms
| Term | Beginner-friendly meaning |
|---|---|
| Command Handler | Processes a command |
| Query Handler | Processes a query |
| Write Model | Handles data modifications |
| Read Model | Represents data for retrieval |
| Event Producer | Creates and publishes events |
| Event Consumer | Receives and processes events |
| Event Bus | Distributes events |
| Event Broker | Messaging infrastructure for event delivery |
| Domain Event | Important business occurrence |
| Event Payload | Data contained in an event |
| Eventual Consistency | Different data representations become consistent over time |
| Idempotency | Repeating an operation doesn't produce duplicate effects |
| Event Sourcing | Stores events as the primary history of state changes |
| Transactional Outbox | Reliably stores events alongside database changes |
| Message Queue | Holds messages until consumers process them |
14. ๐งญ When Do These Concepts Work Together?
| Situation | Useful concept |
|---|---|
Separating get_post() and create_post()
|
CQS |
| Different read and write models | CQRS |
| Sending notifications after a post is created | Event-driven architecture |
| Representing a successful follow action | Domain events |
| Updating a read database asynchronously | CQRS + events |
| Keeping event publication reliable | Transactional outbox |
| Preventing duplicate message processing | Idempotency |
| Keeping complete historical state changes | Event sourcing |
15. ๐ค Interview Questions and Answers
Q1. What is Command-Query Separation?
A design principle that separates operations into Commands, which modify application state, and Queries, which retrieve information without modifying business state.
Q2. What is CQRS?
Command Query Responsibility Segregation: an architectural pattern that separates read and write responsibilities, potentially using different models and data stores.
Q3. What's the difference between CQS and CQRS?
CQS is a principle applied at the operation or method level. CQRS is an architectural pattern that applies the separation more broadly to the application's read and write models.
Q4. What is a Domain Event?
Something important that has already happened in the business domain, such as PostCreated, PaymentCompleted or UserRegistered.
Q5. What's the difference between a Command and an Event?
A Command requests an action. An Event represents a fact that the action has happened.
Q6. What is Event-Driven Architecture?
An approach in which components communicate by publishing and consuming events. It helps decouple components and allows independent processing.
Q7. What is an Event Broker?
Infrastructure that receives and distributes messages between producers and consumers, such as RabbitMQ and Kafka.
Q8. What is Eventual Consistency?
Different data representations may temporarily contain different information but eventually become consistent after updates are processed.
Q9. What is the Transactional Outbox Pattern?
A reliability pattern that stores business data and the corresponding event record in the same database transaction. A background worker later publishes the event.
Q10. Does CQRS require two databases?
No. CQRS can use the same database with separate read and write models. Separate databases are optional.
Q11. Is Event-Driven Architecture the same as Event Sourcing?
No. EDA uses events for communication between components. Event sourcing stores events as the primary record of state changes.
Q12. What are the disadvantages of CQRS?
Architectural complexity, additional code, synchronization challenges, potential eventual consistency, and more difficult debugging.
16. ๐งช Test Your Understanding!
Try these before peeking at the answers! โค๏ธ
-
A user requests their profile details. What is this?
- A) Command
- B) Query
- C) Domain Event
-
A user clicks the Like button. What is the incoming instruction?
- A)
PostLiked - B)
LikePost - C)
GetPost
- A)
-
The backend successfully saves a post. What event can represent this?
- A)
CreatePost - B)
GetPost - C)
PostCreated
- A)
-
A post creation event triggers notifications and analytics independently. Which architecture is this?
- A) Event-Driven Architecture
- B) Event Sourcing
- C) Normalization
-
Does CQRS always require two databases?
- A) Yes
- B) No
-
What helps reliably publish events after a database transaction?
- A) B-tree index
- B) Transactional Outbox
- C) JWT
-
What does Eventual Consistency mean?
- A) Data never changes
- B) All systems update at exactly the same time
- C) Data representations may temporarily differ but eventually catch up
๐ Click to reveal answers
LikePost is the command. PostLiked is the event that followsPostCreated. Events are past-tense facts
17. ๐ Remember These Five Things
- ๐ CQS = separate reading and writing operations
- ๐งฉ CQRS = separate read and write responsibilities/models
- โ๏ธ Command = an instruction to perform an action
- ๐ฃ Domain Event = something meaningful that happened
- ๐ EDA = components react to events and communicate through them
If this post helped you, drop a โค๏ธ or ๐ฆ and share it with a friend learning backend architecture. Happy coding! ๐ฉโ๐ปโจ
Top comments (0)