Skip to main content

Event Sourcing Pattern

This document explains the Event Sourcing implementation in MBC CQRS Serverless.

Event Sourcing Overview

Event Lifecycle

DynamoDB Event Store Schema

Key Structure

The DynamoDB key structure for event storage:

  • PK (Partition Key): {TENANT}#{ENTITY_TYPE} (Example: TENANT001#ORDER)
  • SK (Sort Key): {ENTITY_TYPE}#{ID} (Example: ORDER#20240101-001)

Event Record Example

{
"pk": "TENANT001#ORDER",
"sk": "ORDER#20240101-001",
"version": 3,
"type": "OrderCreated",
"data": {
"orderId": "20240101-001",
"customerId": "CUST-001",
"items": [],
"totalAmount": 15000
},
"createdAt": "2024-01-01T10:00:00Z",
"createdBy": "user-123"
}

Optimistic Locking

Explains the optimistic locking mechanism for ensuring data consistency during concurrent updates.

Version Control Implementation

// Command Service automatically handles versioning
await this.commandService.publish(entity, {
invokeContext: context,
});

// DynamoDB ConditionExpression ensures optimistic locking
// ConditionExpression: 'attribute_not_exists(pk) OR version = :currentVersion'

Event Processing Pipeline

Event Handler Implementation

@EventsHandler(OrderCreatedEvent)
export class OrderCreatedHandler implements IEventHandler<OrderCreatedEvent> {
constructor(
private readonly notificationService: NotificationService,
private readonly readModelService: ReadModelService,
) {}

async handle(event: OrderCreatedEvent): Promise<void> {
// Update read model
await this.readModelService.updateOrderSummary(event);

// Send notification
await this.notificationService.sendOrderConfirmation(event);
}
}

Benefits of Event Sourcing

Adopting Event Sourcing provides these benefits:

  • Complete Audit Trail: All state changes are recorded as events
  • Time Travel: Reconstruct state at any point in time
  • Event Replay: Replay events to rebuild projections
  • Debugging: Trace exact sequence of operations
  • Analytics: Rich event data for business intelligence
  • Integration: Events can trigger external system updates

Best Practices

Best practices for effective Event Sourcing:

  1. Immutable Events: Never modify stored events
  2. Idempotent Handlers: Handle duplicate event delivery gracefully
  3. Event Versioning: Plan for event schema evolution
  4. Correlation IDs: Track related events across services
  5. Dead Letter Queues: Handle failed event processing