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}@{version} (Example: ORDER#20240101-001@1)

Event Record Example​

{
"pk": "TENANT001#ORDER",
"sk": "ORDER#20240101-001@1",
"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.publishAsync(entity, {
invokeContext: context,
});

// DynamoDB ConditionExpression ensures optimistic locking
// ConditionExpression: 'attribute_not_exists(pk) AND attribute_not_exists(sk)'
// sk includes the version number, preventing duplicate command versions

Event Processing Pipeline​

Event Handler Implementation​

import { EventHandler, IEventHandler } from '@mbc-cqrs-serverless/core';

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

async execute(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