Component Overview
Plugin with Aggregates
The following diagram shows how all components work together in a plugin using Aggregates:
- Command Flow: Client → API → CommandGenerator → CommandTopic → Aggregate
- Event Flow: Aggregate → EventLog → EventTopic → EventCollectors → Processing Components
- Read Side: EventCollector → ReadModel → QueryDb ← API ← Client
- Event Processing: EventMapper and SideEffectHandler consuming events
- Plugin System: Cross-plugin communication via ExtensionPoints and Extensions
- Scheduling: Time-based command generation and health monitoring
Plugin with DCB Slices
The following diagram shows how the components work together in a plugin using DCB Slices (Dynamic Consistency Boundary). The key differences from the Aggregate approach are the shared DcbEventLog across all StateChangeSlices and the StateViewSlice that combines the EventCollector and ReadModel roles.
- Command Flow: Client → API → CommandTopic → StateChangeSlices (routed by command type)
- Write Side: Each StateChangeSlice reads from and appends to the shared DcbEventLog with optimistic concurrency
- Event Flow: DcbEventLog → EventTopic → StateViewSlice → QueryDb
- Automation: AutomationSlice consumes events, maintains a TODO list, and issues commands back to CommandTopic
- Outbound Translation: OutboundTranslationSlice consumes events, calls external systems, and optionally publishes commands back
- Inbound Translation: InboundTranslationSlice receives external input (webhooks, API calls), validates and translates it into domain commands
- Read Side: StateViewSlice projects events directly into QueryDb, replacing the EventCollector + ReadModel pair
- Plugin System: Cross-plugin communication via ExtensionPoints and Extensions
- Scheduling: Time-based command generation and health monitoring
Live updates. A QueryDb table can stream its changes to subscribed clients: the QueryDb stream feeds a StateTopic Lambda that publishes to the AppSync Events API. See AppSync Events live updates for the wire path.
Component reference
Each component is documented in detail on its own page. The table below is a one-line map; follow the link for types, operations, and examples.
Write side
| Component | Role | Details |
|---|---|---|
| Aggregate | Transactional unit: handles a command against replayed state, emits events to its own EventLog | aggregate |
| StateChangeSlice | DCB equivalent of an Aggregate: decides against a tag-scoped read of the shared DcbEventLog and appends with optimistic concurrency | statechangeslice |
| EventLog | Append-only per-aggregate event storage with replay; publishes to EventTopic | eventlog |
| DcbEventLog | Shared, tag-queryable event store for DCB slices, with optimistic concurrency | dcbeventlog |
| CommandTopic | FIFO command queue with exactly-once, in-order delivery to handlers | commandtopic |
| CommandGenerator | Turns GraphQL mutations into commands published to a CommandTopic | commandgenerator |
Read side
| Component | Role | Details |
|---|---|---|
| ReadModel | Projects events from one or more Aggregates into persisted, queryable state | readmodel |
| StateViewSlice | DCB equivalent of a ReadModel: projects DcbEventLog events directly into a QueryDb (no separate EventCollector) | stateviewslice |
| QueryDb | Stores denormalized read-model state; serves API queries; supports indexes and TTL | querydb |
| EventTopic | Fans events out from an EventLog to multiple EventCollectors | eventtopic |
| EventCollector | Subscribes to EventTopics and delivers ordered events to ReadModels, EventMappers, and SideEffectHandlers | eventcollector |
Reactions, automation & translation
| Component | Role | Details |
|---|---|---|
| EventMapper | Maps events (from one or more Aggregates) to commands for a target Aggregate | eventmapper |
| AutomationSlice | DCB Automation (TODO-list) pattern: collects work from events, issues commands once, tracks resolution | automationslice |
| InboundTranslationSlice | Anti-corruption layer: validates external input (webhooks/APIs) and translates it into domain commands | inboundtranslationslice |
| OutboundTranslationSlice | Calls external services per event with per-item retry; optionally publishes commands back | outboundtranslationslice |
| SideEffectHandler | Like an EventMapper but targets Tasks/functions outside the command/event paradigm | sideeffecthandler |
| Task | Escape hatch for logic loosely coupled to events — interval jobs, uploads, foreign API calls | task |
| Counter | Atomic counts and dedup, used by EventMappers to avoid duplicate command generation | counter |
Cross-plugin & platform
| Component | Role | Details |
|---|---|---|
| Plugin | A bounded context and deployment unit grouping the components above | plugin |
| ExtensionPoint | A plugin's outbound contract: maps internal events to a stable public event vocabulary | extensionpoint |
| Extension | A plugin's inbound subscription: maps a remote ExtensionPoint's events to local commands | extension |
| Scheduler | Time-based command publishing for scheduled/periodic workflows | scheduler |
| Heartbeat | Periodic health/keepalive signals into the Platform Admin's Plugin ExtensionPoint | heartbeat |