Event-Driven Architecture (EDA): Event-Driven Programming

  


The Event-Driven Architecture (EDA) is a software paradigm where applications communicate through events, in an asynchronous and decoupled manner. It is at the heart of many modern architectures such as microservices, IoT systems, and real-time apps.

🔗 Do you like Techelopment? Check out the site for all the details!


What is an Event-Driven Architecture?

TheEvent-Driven Architecture (EDA) is an architectural model in which system components communicate and react through events. Instead of continuously querying the state of other components (as happens in synchronous systems), each component listens for significant events and only acts when they occur.

An event represents a state change or an action that is relevant to the system, for example:

  • “An order has been created”

  • “A payment has been has been approved”

  • “A sensor has detected an abnormal temperature”


Main Components of an EDA

  1. Event Producer

    This is the component that generates an event when something relevant happens. The producer does not know who will consume the event or how it will be handled.

  2. Event Consumer

    This is the component that receives and reacts to an event. There can be one or more consumers for the same event.

  3. Event Channel

    This is the medium through which events are transmitted. This can be a message broker such as Kafka, RabbitMQ, AWS EventBridge, or simple queues.

  4. Event

    This is the message describing what happened. It is usually structured as a JSON or XML object that contains a type, timestamp, and relevant data.


How does an EDA System work?

Base flow:

  1. A user performs an action (e.g. sends an order).

  2. The system generates an event: 

    {
       type: "CreatedOrder",
       data: {
          id: 123,
          user: "Marco"
       }
    }

  3. The event is published on the channel events.

  4. The affected consumers (e.g. payment system, notification system) receive the event and react autonomously.


EDA


Types of Communication

  • Asynchronous: The general rule. Components don't wait for immediate responses.

  • Decoupled: Producers and consumers are not directly connected.

  • Pub/Sub (Publish/Subscribe): Producers publish events, and those interested “subscribe” to receive them.


Advantages of EDA

Scalability: Each component can scale independently based on event load.

Decoupling: Components are autonomous and do not need to know each other, facilitating maintainability and system evolution.

Responsiveness: The system can respond quickly to external or internal conditions.

Audit & Logging natural: Events create a natural historical trail of what happened in the system.


Disadvantages of EDA

⚠️ Complex debugging: Tracing the path of an event can be difficult in distributed environments.

⚠️ Time dependency management: Events can arrive in order wrong, or multiple times, or get lost without the right mechanisms.

⚠️ Testing Difficulties: Testing asynchronous systems requires specific strategies.

⚠️ Weak Contracts: Without a common structure for events, communication can become fragile (e.g. a change in an event can break consumers).


Practical Example

Let's imagine an e-commerce app:

  1. Effective Useryour an order

  2. The system publishes an event OrderCreated

  3. Three services react:

    • Payment Service → prepare the invoice

    • Notification Service → send an email

    • Logistics Service → prepare the shipment

Neither of these services should call the other directly. Everyone listens to events and acts according to their own logic.


Popular Technologiesri for EDA

  • Apache Kafka

  • RabbitMQ

  • Amazon SNS/SQS (in combination with AWS Lambda)

  • Azure Event Grid

  • Google Pub/Sub

  • NATS, Redis Streams, MQTT (for IoT)


☁️ Example with AWS Lambda + SQS (Node.js)

🎯 Goal

When a message is sent to an SQS queue, an AWS Lambda function automatically triggers, reads the message, and executes some logic (e.g., print order received, send email, etc.).


🧱 Architecture Structure

Example flow

⚙️ 1. Creating the SQS Queue

  1. Sign in to the console: https://console.aws.amazon.com/sqs

  2. Click on “Create Queue”

  3. Set:

    • Type: Standard

    • Name: OrdersQueue

  4. Leave the other default settings and create the queue


🖥️ 2. Creating the Lambda Function

  1. Go to: https://console.aws.amazon.com/lambda

  2. Click on “Create function”

  3. Set:

    • Function Name: OrderManagement

    • Runtime: Node.js 18.x (or similar)

    • Permissions: Create a new role with basic permissions

  4. Click on “Create Function”


📎 3. Connect SQS as Lambda trigger

  1. Within the Lambda function, click "Add trigger"

  2. Select:

    • Service: SQS

    • Queue: Select OrdersQueue

  3. Save

This connects the queue to the Lambda function: every new message automatically triggers the function.


✏️ 4. Write the Lambda code

In your Lambda dashboard, scroll down to “Code”.

Replace the code with this:

// handler.js
exports.handler = async (event) => {
    for (const record of event.Records) {
        const order = JSON.parse(record.body);
        console.log(`📦 Order received: ID ${order.id}, Customer: ${order.customer}, Amount: €${order.amount}`);
        // Here you can insert notification logic, email sending, DB saving, etc.
    }

    return {
        statusCode: 200,
        body: JSON.stringify('Order successfully processed'),
    };
};

📌 The function is invoked with a event containing an array of SQS messages (event.Records)

📤 5. Send a message to the queue

You can do it in two ways:

A. Via AWS Console:

  1. Go to SQS > OrdersQueue > “Send and receive messages”

  2. Enter a JSON like this:

{ 
    "id": 123, 
    "customer": "Marco", 
    "amount": 89.90
}
  1. Click “Send Message”

B. Via AWS CLI:

>aws sqs send-message \ 
--queue-url https://sqs.<region>.amazonaws.com/<account-id>/OrdersQueue \ 
--message-body '{"id": 123, "customer": "Marco", "amount": 89.90}'

Replace <region> (e.g. eu-west-1) and <account-id> with your values.


✅ Expected Result

Whenever you send a message to the queue:

  • Lambda is automatically activated

  • The message is read

  • It is printed in Lambda function log

👉 Go to Monitoring > View logs in CloudWatch to see the output!


🧠 What did you get

  • event-driven serverless architecture

  • No servers to manage

  • Automatic Responsiveness and Scalability

  • Logic written in Node.js with instant deployment


🔐 Permissions (IAM Policy)

Make sure your Lambda has access to the SQS queue. If you used the default settings, AWS does this automatically. Otherwise, the Lambda role must have at least this policy:

{
    "Effect": "Allow",
    "Action": ["sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes"],
    "Resource": "arn:aws:sqs:REGIONE:ACCOUNT_ID:OrdersQueue"
}

When to Use an Event-Driven Architecture?

✅ When you need high scalability
✅ When you want decoupling between components
✅ For systems with lots of asynchronous or real-time events
✅ For complex microservices with reactive flows

Not ideal for very simple systems or where immediate consistency is crucial without delay tolerance.


Conclusion

Event-Driven Architecture is a powerful and flexible paradigm for building modern, resilient, and scalable systems. It requires good design and attention to details (such as error handling, event ordering, idempotence), but offers huge benefits especially in distributed or microservice environments.



Follow me #techelopment

Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment