Alpha Version: You are viewing the ALPHA documentation. This is an experimental version and may contain breaking changes.
Skip to main content

EventTopic

For a short summary of EventTopic, see Reventless Components Overview.

Framework Implementation

This component follows the Reventless Component Structure Pattern, using separate files for interface definitions (EventTopic.res), builder logic (EventTopic_Builder.res), adapter interface (EventTopic_Adapter.res), and runtime operations (EventTopic_Operations.res).

Overview

d2 diagram

The EventTopic is the event distribution component that enables fan-out delivery of events to multiple subscribers. It receives events from the EventLog and distributes them to EventCollectors, which then deliver events to ReadModels, EventMappers, and SideEffectHandlers.

Purpose and Responsibilities

  • Responsibility: Distribute events from EventLog to multiple subscribers; enable fan-out pattern for event-driven architecture; provide ordering guarantees per aggregate
  • In: Events from EventLog (via publish operation)
  • Out: Events to EventCollectors (via SNS subscriptions)

Component Spec

The EventTopic requires a spec defining the aggregate's event type:

module type Spec = {
@schema
type event
}

For example, a Customer aggregate might define its spec as follows:

Customer.res
@@reventless.spec

@schema
type event =
| Created({name: string, address: string})
| AddressChanged(string)
| NameChanged(string)
| Deleted

This spec is used to create a type-safe EventTopic for the Customer aggregate.

Usage Pattern

EventTopics are typically created as part of an EventLog component and are not used directly by application code. The EventLog handles all interactions with the EventTopic internally.

Creating an EventTopic

Customer_EventLog.res
module CustomerEventTopic = Reventless.EventTopic_Builder.Make(
Customer,
EventTopicPublisher_SNS,
)

let eventTopic = CustomerEventTopic.make(
~name="Customer",
~storageResources=eventLogResources,
~opts=pulumiOptions,
)

EventTopic Operations

The EventTopic provides operations for publishing events:

Publish Operation

The publish operation sends events to the topic for distribution:

type publish<'id, 'event> = (
array<Message.event'<'id, 'event>>
) => promise<unit>

Usage:

let events' = [
{
Message.id: customerId,
event: Created({name: "John Doe", address: "123 Main St"}),
meta: {...},
},
]

await eventTopic.publish(events')

Publish JSON Operation

The publishJson operation publishes a single event in JSON format:

type publishJson = (
string, // aggregate id
Message.meta, // event metadata
Js.Json.t // event JSON
) => promise<unit>

This is used internally by the EventLog after storing events.

Runtime Behavior

Event Publishing Flow

d2 diagram

Integration with EventLog

The EventTopic is automatically created and managed by the EventLog component:

d2 diagram

Flow:

  1. Aggregate appends events to EventLog storage
  2. After successful storage, EventLog publishes to EventTopic
  3. EventTopic distributes events to all subscribers

Event Metadata

All events published to the EventTopic include metadata:

type event'<'id, 'event> = {
id: 'id, // Aggregate instance ID
meta: meta, // Metadata
event: 'event, // The actual domain event
}

type meta = {
service: service, // service name that created event or is addressed by command
time: string, // when message was created
ip: string, // IP of service that created message
user: string, // user name that initiated message (if any)
msgId: string, // unique message id
correlationId: string, // id of message that caused this message
}

This metadata enables:

  • Event tracing across the system
  • Debugging event flows
  • Auditing who initiated events
  • Causality tracking for event sourcing

Common Patterns

Event Fan-out to Multiple Consumers

d2 diagram

Event-Driven Saga Pattern

// Order aggregate publishes OrderCreated event
// EventTopic distributes to:
// 1. Inventory EventMapper -> Reserve inventory
// 2. Payment EventMapper -> Process payment
// 3. Notification SideEffectHandler -> Send confirmation email

Cross-Plugin Event Distribution

// Plugin A's EventTopic publishes events
// Plugin B's Extension subscribes via ExtensionPoint
// Events flow across plugin boundaries

Pulumi

The EventTopic component creates these infrastructure resources:

type outputs = {
resources: array<resource>, // adapter resources
}

Resource Naming:

  • Component type: reventless:EventTopic
  • Resource name pattern: {aggregateName}EventTopic

Dependencies:

  • EventLog depends on EventTopic (events published after storage)
  • EventCollectors subscribe to EventTopic

AWS Implementation

For detailed implementation, see EventTopic AWS Adapter Documentation.