AWS EventBridge
Commercial
Specmatic-async provides first-class support for contract testing applications that use AWS EventBridge, enabling you to validate event-driven architectures with confidence.
What is AWS EventBridge?
AWS EventBridge is a serverless event bus service that makes it easy to connect applications using events. It acts as a central event routing layer that receives events from various sources and delivers them to target services based on configurable rules.
Key Concepts
- Event Bus: A central router that receives events from event sources and routes them to target destinations
- Events: JSON-formatted data records that represent state changes or significant occurrences in your application
- Rules: Pattern-matching criteria that determine which events are routed to which targets
- Targets: Destinations where events are delivered (e.g., SQS queues, Lambda functions, SNS topics)
Common Use Cases
EventBridge is commonly used for:
- Building loosely coupled, event-driven microservices architectures
- Integrating SaaS applications with custom applications
- Implementing pub/sub messaging patterns at scale
- Routing events to different services based on event content
Specifying EventBridge in AsyncAPI
Specmatic-async uses AsyncAPI 3.0 specifications to define EventBridge contracts. Here’s how to configure EventBridge in your AsyncAPI specification:
Server Configuration
Define an EventBridge server in the servers section:
servers:
eventBridgeServer:
host: 'http://localhost:4566'
protocol: eventbridge
description: AWS EventBridge server for receiving order events
For production environments, you would use the actual AWS EventBridge endpoint:
servers:
eventBridgeServer:
host: 'https://events.us-east-1.amazonaws.com'
protocol: eventbridge
description: AWS EventBridge production server
Channel Configuration
Define the EventBridge event bus as a channel:
channels:
orderEventsBus:
address: order-events-bus
servers:
- $ref: '#/servers/eventBridgeServer'
messages:
placeOrderEvent:
$ref: '#/components/messages/PlaceOrderEvent'
cancelOrderEvent:
$ref: '#/components/messages/CancelOrderEvent'
description: EventBridge bus where order events are published
The address field specifies the name of the EventBridge event bus.
Message Schema with EventBridge Headers
EventBridge messages require specific headers for routing. Define them in your message schemas:
components:
schemas:
EventBridgeHeaders:
type: object
properties:
detail-type:
type: string
description: EventBridge detail type for routing
source:
type: string
description: Source of the event
examples:
- order-service
messages:
PlaceOrderEvent:
name: PlaceOrderEvent
title: Place Order Event
summary: Event triggered when a new order is placed
contentType: application/json
headers:
$ref: '#/components/schemas/EventBridgeHeaders'
payload:
$ref: '#/components/schemas/PlaceOrderEventPayload'
The detail-type header is crucial as it’s commonly used in EventBridge rules to route events to appropriate targets.
Defining Operations
Specify operations that describe how your application interacts with EventBridge:
operations:
receivePlaceOrderEvent:
description: Receive a place-order event from EventBridge and publish the processed message to the place-order Kafka topic
action: receive
channel:
$ref: '#/channels/orderEventsBus'
messages:
- $ref: '#/channels/orderEventsBus/messages/placeOrderEvent'
reply:
channel:
$ref: '#/channels/placeOrderTopic'
messages:
- $ref: '#/channels/placeOrderTopic/messages/placeOrderProcessed'
The action: receive indicates that your application consumes events from EventBridge. If you have a reply channel (as shown above), it describes what happens after processing the event.
Contract Testing with Specmatic-async
Specmatic-async enables you to validate that your application correctly handles EventBridge events according to your AsyncAPI specification.
For a complete working example of AWS Eventbridge contract testing with Specmatic-Async, refer to the specmatic-event-bridge-sample project.
Setting Up Contract Tests
1. Create the AsyncAPI Specification
Create your AsyncAPI specification file (e.g., spec/order-events-async-api.yaml) as described in the previous section.
2. Configure Specmatic
Create a specmatic.yaml file to configure Specmatic-async:
version: 2
contracts:
- provides:
- specs:
- spec/order-events-async-api.yaml
specType: asyncapi
config:
servers:
- host: http://localhost:4566
protocol: eventbridge
adminCredentials:
region: us-east-1
aws.access.key.id: test
aws.secret.access.key: test
- host: localhost:9092
protocol: kafka
The adminCredentials section provides AWS credentials needed to interact with EventBridge (use test credentials for LocalStack).
3. Set Up Infrastructure
For local testing, use Docker Compose to set up LocalStack (AWS simulation) and any other required services:
services:
localstack:
image: localstack/localstack:latest
ports:
- "4566:4566"
environment:
- SERVICES=events,sqs
- AWS_DEFAULT_REGION=us-east-1
volumes:
- "./localstack-init:/etc/localstack/init/ready.d"
Create an initialization script to set up EventBridge resources (localstack-init/init.sh):
#!/bin/bash
# Create EventBridge event bus
aws events create-event-bus --name order-events-bus \
--endpoint-url=http://localhost:4566 \
--region=us-east-1
# Create SQS queue (as a target for EventBridge)
aws sqs create-queue --queue-name order-events-queue \
--endpoint-url=http://localhost:4566 \
--region=us-east-1
# Create EventBridge rule
aws events put-rule \
--name place-order-rule \
--event-bus-name order-events-bus \
--event-pattern '{"detail-type":["place-order-event"]}' \
--state ENABLED \
--endpoint-url=http://localhost:4566 \
--region=us-east-1
# Add SQS queue as target
aws events put-targets \
--rule place-order-rule \
--event-bus-name order-events-bus \
--targets "Id"="1","Arn"="arn:aws:sqs:us-east-1:000000000000:order-events-queue" \
--endpoint-url=http://localhost:4566 \
--region=us-east-1
Start the infrastructure:
docker compose up -d
4. Run Your Application
Start your application that implements the AsyncAPI specification. The application should be configured to connect to the EventBridge service and publish/consume events as defined in your contract.
5. Run Contract Tests
Execute the contract tests using the Specmatic Docker image:
docker run --network host -v "$PWD/specmatic.yaml:/usr/src/app/specmatic.yaml" -v "$PWD/spec:/usr/src/app/spec" specmatic/specmatic-async test
Specmatic-async will:
- Read the AsyncAPI specification and identify EventBridge channels
- Connect to the configured EventBridge service
- Send test events to your application
- Validate that your application produces correct events with proper detail-type and payload structure
- Verify that all events conform to the contract
6. Review Test Results
Check the test output for detailed validation results, including any contract violations or failures.
How Contract Testing Works
When you run Specmatic-async contract tests against an EventBridge-based application:
-
Specmatic reads the AsyncAPI specification to understand the expected event schemas and message flows
- Specmatic generates test events based on the schemas defined in your specification, including:
- Valid events with proper EventBridge headers (
detail-type,source) - Edge cases and boundary values
- Invalid events to verify error handling
- Valid events with proper EventBridge headers (
-
Specmatic publishes events to EventBridge using the configured event bus
-
Your application consumes and processes the events (typically via SQS queue targets)
- Specmatic validates the output by checking:
- Events are correctly routed based on
detail-type - Payload structure matches the schema
- Response/reply messages (if defined) match expectations
- Message flow follows the defined operations
- Events are correctly routed based on
- Test results are generated showing which scenarios passed or failed
Best Practices
Use Meaningful Event Types
Define clear and descriptive detail-type values in your headers:
headers:
type: object
properties:
detail-type:
type: string
enum:
- place-order-event
- cancel-order-event
- update-order-event
Include Comprehensive Examples
Provide realistic examples in your schemas to help with test data generation:
PlaceOrderEventPayload:
type: object
properties:
orderId:
type: string
examples:
- ORD-001
- ORD-12345
customerId:
type: string
examples:
- CUST-123
timestamp:
type: string
format: date-time
examples:
- '2025-12-24T10:00:00Z'
Define Required Fields
Always specify which fields are required:
required:
- timestamp
- orderId
- customerId
- items
- totalAmount
Use Separate Event Buses for Different Domains
For complex applications, use multiple event buses to separate concerns:
channels:
orderEventsBus:
address: order-events-bus
description: Events related to order management
paymentEventsBus:
address: payment-events-bus
description: Events related to payment processing
Version Your Events
Include version information in your event schemas:
properties:
eventVersion:
type: string
const: "1.0"
eventType:
type: string
const: place-order-event
Benefits of Contract Testing EventBridge Applications
-
Early Detection of Integration Issues: Catch schema mismatches and routing problems before deployment
-
Documentation as Code: Your AsyncAPI specification serves as living documentation of your event-driven architecture
-
Safe Refactoring: Change your event schemas with confidence, knowing tests will catch breaking changes
-
Decoupled Development: Teams can develop producers and consumers independently as long as they adhere to the contract
-
Reduced Testing Overhead: Automated contract tests reduce the need for extensive integration testing
-
Production Confidence: Deploy knowing your application correctly handles all event types defined in your contract
Troubleshooting
Events Not Being Received
- Verify EventBridge rules are correctly configured with proper event patterns
- Check that the
detail-typein published events matches rule patterns - Ensure SQS queue is properly configured as a target for EventBridge rules
- Verify AWS credentials are correctly configured in
specmatic.yaml
Contract Test Failures
- Review the test output to identify which scenarios are failing
- Check that your application correctly handles all event types defined in the AsyncAPI spec
- Verify message schemas in your application match the AsyncAPI definitions
- Ensure proper error handling for invalid events
LocalStack Connection Issues
- Confirm LocalStack container is running:
docker ps - Check LocalStack health:
curl http://localhost:4566/_localstack/health - Verify network configuration allows container-to-container communication
- Review LocalStack logs:
docker logs localstack
Example Repository
For a complete working example, see the specmatic-event-bridge-sample repository, which demonstrates:
- A complete AsyncAPI specification for EventBridge
- Application that consumes EventBridge events and publishes to Kafka
- Contract tests using Specmatic-async
- LocalStack setup for local testing
- Docker Compose configuration for the entire stack