EventBridge is a serverless event bus that makes it easy to connect applications together using data from your own applications, integrated SaaS applications, and AWS services.
Let’s see it in action. Imagine we have a simple e-commerce application. When a new order is placed, we want to:
- Send a confirmation email to the customer.
- Update inventory levels.
- Notify the shipping department.
Traditionally, this would involve direct API calls between services, leading to tight coupling. With EventBridge, we can decouple these actions.
Here’s a simplified representation of our order service:
# order_service.py
import boto3
import json
import uuid
eventbridge = boto3.client('events')
def create_order(order_details):
order_id = str(uuid.uuid4())
event_data = {
"source": "com.ecommerce.orders",
"detail-type": "OrderCreated",
"detail": {
"order_id": order_id,
"customer_email": order_details["email"],
"items": order_details["items"],
"timestamp": "2023-10-27T10:00:00Z"
},
"eventBusName": "default" # Or your custom event bus name
}
response = eventbridge.put_events(
Entries=[event_data]
)
print(f"Order created: {order_id}. EventBridge response: {response}")
return order_id
# Example usage:
# new_order = {"email": "customer@example.com", "items": [{"sku": "ABC", "quantity": 2}]}
# create_order(new_order)
When create_order is called, it doesn’t directly call the email, inventory, or shipping services. Instead, it publishes an OrderCreated event to the EventBridge event bus.
Now, we need to set up rules on EventBridge to react to this event.
In the AWS console, we’d navigate to EventBridge and create a new rule.
Rule 1: Send Confirmation Email
- Event Bus:
default - Event Pattern:
{ "source": ["com.ecommerce.orders"], "detail-type": ["OrderCreated"] } - Target: An AWS Lambda function named
send_confirmation_email_lambda.
The Lambda function would look something like this:
# send_confirmation_email_lambda.py
import json
def lambda_handler(event, context):
order_id = event['detail']['order_id']
customer_email = event['detail']['customer_email']
print(f"Sending confirmation email for order {order_id} to {customer_email}")
# Logic to send email using SES or another service
return {
'statusCode': 200,
'body': json.dumps('Email sent!')
}
This Lambda function receives the OrderCreated event, extracts the necessary details, and sends an email.
Rule 2: Update Inventory
- Event Bus:
default - Event Pattern: Same as above.
- Target: An AWS Lambda function named
update_inventory_lambda.
# update_inventory_lambda.py
import json
def lambda_handler(event, context):
order_id = event['detail']['order_id']
items = event['detail']['items']
print(f"Updating inventory for order {order_id} with items: {items}")
# Logic to decrement inventory counts for each item SKU
return {
'statusCode': 200,
'body': json.dumps('Inventory updated!')
}
Rule 3: Notify Shipping
- Event Bus:
default - Event Pattern: Same as above.
- Target: An AWS SQS queue named
shipping-notifications-queue.
This demonstrates how EventBridge acts as a central hub, decoupling the order service from the downstream consumers. The order service only needs to know about publishing events to EventBridge, not about the existence or specifics of the email, inventory, or shipping services.
The real power of EventBridge lies in its ability to filter events with sophisticated patterns and route them to various AWS services or even external SaaS applications. You can define rules that match specific values within the event payload, allowing for fine-grained control over which events trigger which actions. For instance, you could have a separate rule for orders over a certain value to trigger a fraud check.
One of the most powerful, yet often overlooked, aspects of EventBridge is its ability to transform event payloads before they reach the target. Using Input Transformers, you can reshape the incoming event data into a format that is perfectly suited for your target service, without needing to write custom code in your Lambda functions or other consumers to parse and reformat the data. This can significantly simplify your target service logic and reduce the amount of boilerplate code you need to manage. For example, you might want to extract only the order_id and customer_email and send them as separate parameters to an API endpoint.
The next step in building robust event-driven systems is to manage dead-letter queues for failed events.