ddd-event-driven
When to use this skill
Use this skill whenever the user wants to:
- Use domain events to decouple aggregates and services
- Design event sourcing systems where state is derived from an event stream
- Implement CQRS (Command Query Responsibility Segregation)
- Choose and integrate message brokers (Kafka, RabbitMQ, etc.)
- Ensure reliable event delivery with outbox patterns
How to use this skill
Workflow
- Identify domain events that represent "facts that have happened" within aggregates
- Design the event flow: publication, transport (message bus), and consumption
- Choose the pattern: simple domain events, event sourcing, or full CQRS
- Implement delivery guarantees: at-least-once delivery with idempotent consumers
1. Domain Event Definition
public record OrderPlacedEvent(
String orderId,
String customerId,
BigDecimal totalAmount,
Instant occurredAt
) implements DomainEvent {}
2. Publishing Domain Events
public class Order extends AggregateRoot {
public void place(List<OrderItem> items) {
// Business logic...
this.status = OrderStatus.PLACED;
registerEvent(new OrderPlacedEvent(this.id, this.customerId, this.total, Instant.now()));
}
}
3. Event Sourcing Pattern
public class Account {
private BigDecimal balance = BigDecimal.ZERO;
private final List<DomainEvent> changes = new ArrayList<>();
public void apply(MoneyDepositedEvent event) {
this.balance = this.balance.add(event.amount());
}
public static Account reconstitute(List<DomainEvent> events) {
Account account = new Account();
events.forEach(account::apply);
return account;
}
}
4. CQRS Overview
Write Side: Read Side:
Command → Aggregate → Events → Event Handler → Read Model (View)
(message bus)
5. Outbox Pattern for Reliable Delivery
// Save event to outbox table in the same transaction as the aggregate
@Transactional
public void placeOrder(PlaceOrderCommand cmd) {
Order order = Order.place(cmd);
orderRepository.save(order);
outboxRepository.save(new OutboxEntry("OrderPlaced", serialize(order.events())));
}
// A separate poller publishes outbox entries to the message broker
Best Practices
- Name events in past tense; include the aggregate ID and essential data only — avoid large payloads or sensitive information
- Guarantee at-least-once delivery with idempotent consumers; use an outbox table with polling for reliable publishing
- Define an explicit event versioning and compatibility strategy (additive fields, new topics)
- Start with simple domain events before adopting full event sourcing; the complexity trade-off must be justified
Resources
- Domain-Driven Design by Eric Evans
- Martin Fowler on Event Sourcing: https://martinfowler.com/eaaDev/EventSourcing.html
- CQRS: https://martinfowler.com/bliki/CQRS.html
Keywords
event-driven architecture, domain events, event sourcing, CQRS, outbox pattern, message broker, Kafka, RabbitMQ, eventual consistency, idempotent consumers
More from partme-ai/full-stack-skills
vite
Guidance for Vite using the official Guide, Config Reference, and Plugins pages. Use when the user needs Vite setup, configuration, or plugin selection details.
68element-plus-vue3
Provides comprehensive guidance for Element Plus Vue 3 component library including installation, components, themes, internationalization, and API reference. Use when the user asks about Element Plus for Vue 3, needs to build Vue 3 applications with Element Plus, or customize component styles.
63vue3
Guidance for Vue 3 using the official guide and API reference. Use when the user needs Vue 3 concepts, patterns, or API details to build components, apps, and tooling.
54electron
Build cross-platform desktop applications with Electron, covering main/renderer process architecture, IPC communication, BrowserWindow management, menus, tray icons, packaging, and security best practices. Use when the user asks about Electron, needs to create desktop applications, implement Electron features, or build cross-platform desktop apps.
51uniapp-project
Provides per-component and per-API examples with cross-platform compatibility details for uni-app, covering built-in components, uni-ui components, and APIs (network, storage, device, UI, navigation, media). Use when the user needs official uni-app components or APIs, wants per-component examples with doc links, or needs platform compatibility checks.
40ascii-cli-logo-banner
Entry point for ASCII CLI banners that routes to the Python built-in font skill or figlet.js/FIGfont skill. Use when the user wants a startup banner, ASCII logo, terminal welcome screen, or CLI branding for a service.
38