Event-Driven Architecture: Know your commands from your events


Events and Commands are often used side-by-side in event-driven architectures.

Knowing their differences is important so you can choose the right approach to handling them and choose the right technology stack.

Event vs. Command

An event is a notification that something has already happened. It's a fact, and it’s immutable. e.g. a customer placed an order. Events are not directed at anyone, and we don't care how many (if any) subscribers are listening.

A command is a request to perform a specific action. It’s not just information; it’s an instruction, such as a command to process a payment. Commands are directed at an intended recipient who is responsible for fulfilling the requested action.

We often want to know the result of the action. As such, a command is often followed by an event to report the outcome of the action. e.g. a "process_payment" command is followed by a "payment_succeeded" event upon completion.

Pros & Cons

Events promote loose coupling but make systems less predictable and complex, especially when it comes to handling failures.

Commands simplify your control flow as you know where each command is going, making them easier to debug too. But you increase the coupling between components.

What to use as the bus

Regarding technology choices, EventBridge and SNS are good choices for the event bus, which must broadcast events to multiple subscribers.

SQS is not suitable here because it doesn't do broadcasts.

But SQS is a great fit for the command bus precisely because it’s a targeted delivery where you would have only one subscriber per queue.

Also, messages stay on the queue until they are either expired or processed, which is an important requirement for commands.

Event Sourcing & CQRS

Finally, patterns such as event sourcing & CQRS combine both events and commands to great effect.

Event Sourcing ensures that every change is captured as an event, as you model your system’s state as a series of events rather than snapshots.

CQRS separates read and write operations to optimize performance, where the write operations are modelled as commands.

More on event sourcing and CQRS another time!

Master Serverless

Join 17K readers and level up you AWS game with just 5 mins a week.

Read more from Master Serverless

AppSync doesn’t allow unauthenticated API calls. To allow users to call your API without first authenticating themselves, you must mimic the behaviour using one of the available authorization methods [1]. In this post, let’s look at three ways to implement unauthenticated GraphQL operations with AppSync and their pros & cons. API Keys To use API keys, you need to: Add an API Key in AppSync. Pass the API Key in the x-api-key header. That’s it! It’s the easiest and most common way to implement...

A common challenge when building APIs is supporting multiple live versions without letting the system turn into an unmaintainable mess. You need to keep older versions running for existing clients, roll out new versions safely, and avoid breaking changes that might take down production. And you need to do all that without duplicating too much infrastructure or introducing spaghetti logic inside your code. There’s no official pattern for versioning APIs in API Gateway + Lambda. API Gateway...

I recently shared six event versioning strategies for event-driven architectures [1]. In response to this, Marty Pitt reached out and showed me how Orbital [2] and Taxi [3] use semantic tags to eliminate schema coupling in event-driven architectures and simplify the schema management. It's a novel way to manage schema evolution, and I want to share what I learnt with you. Problems with Schema Coupling In an event-driven architecture, event consumers are typically coupled to the schema of the...