Enriching Event Streams#
Event stream enrichment allows applications to inject metadata into events as they flow through the system. This metadata provides contextual information like the current tenant, authenticated user, or correlation keys.
Enrichment occurs after the model records events but before they are persisted to EventStore or published to EventBus.
Understanding stream enrichment#
An application should have a single implementation of StreamEnricherInterface:
| |
Using a single enricher avoids metadata conflicts, ensures predictable execution order, and simplifies configuration. The enricher’s role is to inject metadata into events. This implementation can receive services as dependencies when contextual information is needed. Common metadata includes:
- Current tenant in multi-tenant applications
- Authenticated user information
- Correlation IDs for request tracing
- Execution context (batch job, API request, CLI command)
Creating a stream enricher#
Here’s an example enricher that adds tenant and user information:
| |
This enricher receives services as dependencies and uses them to inject relevant metadata into every event.
Registering the enricher#
Backslash provides two middleware for stream enrichment, as introduced in section 14:
- StreamEnricherEventStoreMiddleware: Enriches events before persisting to EventStore
- StreamEnricherEventBusMiddleware: Enriches events before publishing to EventBus
Register both middleware during application bootstrap to ensure consistent metadata in storage and when published:
| |
Using enriched metadata#
Enriched metadata becomes available throughout the application. Event handlers can access this metadata to make decisions or add context:
| |
Queries can also filter events based on enriched metadata:
| |
Best practices#
Use one enricher per application. Create a single StreamEnricherInterface implementation that handles all metadata
injection; avoid multiple enrichers with overlapping concerns.
Inject services as dependencies when needed. If the enricher requires contextual information, pass services like authentication, tenant management, or correlation tracking as constructor dependencies rather than accessing global state.
Register both middleware. Always register StreamEnricherEventStoreMiddleware and
StreamEnricherEventBusMiddleware to ensure metadata consistency between persisted events and published events.
Enrich metadata, not payloads. Event payloads should contain domain information; metadata is for technical concerns like tenant context, user information, or correlation IDs.
Avoid sensitive data. Metadata is stored and potentially logged; avoid adding passwords, tokens, or other sensitive information unless absolutely required.
Keep enrichment fast. Enrichment runs for every event; avoid expensive operations like database queries or external API calls.