Skip to content

Commit b423a0a

Browse files
committed
docs(guides): audit correlation causation guide
1 parent 59ca5af commit b423a0a

1 file changed

Lines changed: 21 additions & 23 deletions

File tree

docs/guides/correlation-causation-guide.md

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,11 @@ The Book Store API implements **causation** and **correlation** IDs for distribu
3434

3535
### Response Headers
3636

37-
`MartenMetadataMiddleware` automatically echoes the correlation ID in every response. `EventMetadataService.SetResponseHeaders()` additionally emits `X-Event-ID` when an endpoint explicitly creates event metadata.
37+
`MartenMetadataMiddleware` automatically echoes the correlation ID in every response.
3838

3939
| Header | Description | Example |
4040
|--------|-------------|---------|
4141
| `X-Correlation-ID` | Echo of the request correlation ID (or generated) | `019541ab-1234-7000-a000-000000000001` |
42-
| `X-Event-ID` | ID of the event appended during this request | `019541ab-9abc-7000-c000-000000000003` |
4342

4443
## Event Metadata Structure
4544

@@ -86,7 +85,6 @@ curl -X POST http://localhost:5000/api/admin/books \
8685
**Response Headers**:
8786
```
8887
X-Correlation-ID: 019541ab-1234-7000-a000-000000000001
89-
X-Event-ID: 019541ab-9abc-7000-c000-000000000003
9088
```
9189

9290
**Event Stored**:
@@ -112,8 +110,6 @@ curl -X POST http://localhost:5000/api/admin/books \
112110
-d '{"title": "Domain-Driven Design", ...}'
113111
```
114112

115-
Response: `X-Event-ID: 019541ab-bbbb-7000-a000-000000000001`
116-
117113
**Step 2: Update Book (using previous event as causation)**
118114
```bash
119115
curl -X PUT http://localhost:5000/api/admin/books/019541ab-0004-7000-a000-000000000001 \
@@ -123,8 +119,6 @@ curl -X PUT http://localhost:5000/api/admin/books/019541ab-0004-7000-a000-000000
123119
-d '{"title": "Domain-Driven Design (Revised)", ...}'
124120
```
125121

126-
Response: `X-Event-ID: 019541ab-cccc-7000-a000-000000000001`
127-
128122
**Event Chain**:
129123
```mermaid
130124
graph TD
@@ -145,24 +139,18 @@ Imagine a workflow where creating a book triggers multiple operations:
145139
POST /api/admin/publishers
146140
X-Correlation-ID: 019541ab-1111-7000-a000-000000000001
147141
```
148-
Response: `X-Event-ID: 019541ab-2222-7000-a000-000000000001`
149-
150142
**2. Create Author**
151143
```bash
152144
POST /api/admin/authors
153145
X-Correlation-ID: 019541ab-1111-7000-a000-000000000001
154146
X-Causation-ID: 019541ab-2222-7000-a000-000000000001
155147
```
156-
Response: `X-Event-ID: 019541ab-3333-7000-a000-000000000001`
157-
158148
**3. Create Category**
159149
```bash
160150
POST /api/admin/categories
161151
X-Correlation-ID: 019541ab-1111-7000-a000-000000000001
162152
X-Causation-ID: 019541ab-3333-7000-a000-000000000001
163153
```
164-
Response: `X-Event-ID: 019541ab-4444-7000-a000-000000000001`
165-
166154
**4. Create Book**
167155
```bash
168156
POST /api/admin/books
@@ -174,8 +162,6 @@ X-Causation-ID: 019541ab-4444-7000-a000-000000000001
174162
"categoryIds": ["..."]
175163
}
176164
```
177-
Response: `X-Event-ID: 019541ab-5555-7000-a000-000000000001`
178-
179165
**Complete Event Chain**:
180166
```mermaid
181167
graph TD
@@ -228,13 +214,13 @@ curl -H "X-Correlation-ID: $CORRELATION_ID" ...
228214
### 2. Use Event IDs as Causation IDs
229215
When one operation triggers another, use the previous event ID as the causation ID:
230216
```bash
231-
# First call
217+
# First call (capture created entity/event details from response body or stream)
232218
RESPONSE=$(curl -i -X POST ... -H "X-Correlation-ID: $CORRELATION_ID")
233-
EVENT_ID=$(echo "$RESPONSE" | grep "X-Event-ID:" | tr -d '\r' | awk '{print $2}')
219+
# Note: the API does not currently return X-Event-ID response headers.
234220

235221
# Second call caused by first
236222
curl -H "X-Correlation-ID: $CORRELATION_ID" \
237-
-H "X-Causation-ID: $EVENT_ID" \
223+
-H "X-Causation-ID: <previous-event-id>" \
238224
...
239225
```
240226

@@ -302,9 +288,9 @@ _logger.LogInformation("Processing {EventType}. CorrelationId: {CorrelationId}",
302288
- Reads `CorrelationId`/`CausationId` preferring `HttpContext.Items` (set by `MartenMetadataMiddleware`) then falls back to headers and `Activity`.
303289

304290
4. **`EventMetadataService`** (`Infrastructure/EventMetadataService.cs`):
305-
- Not a middleware — a scoped service used by endpoint handlers.
291+
- Not a middleware — a scoped service available for endpoint/handler use.
306292
- `CreateMetadata()` builds an `EventMetadata` record containing a fresh `Guid.CreateVersion7()` event ID plus `CorrelationId`, `CausationId`, and `UserId` read from `IHttpContextAccessor`.
307-
- `SetResponseHeaders()` writes `X-Correlation-ID` and `X-Event-ID` to the response — endpoints call this explicitly after appending events.
293+
- `SetResponseHeaders()` exists, but endpoints do not currently call it; `X-Event-ID` is not emitted in API responses.
308294

309295
### Blazor Frontend Implementation
310296

@@ -322,7 +308,7 @@ The Blazor frontend automatically manages and propagates these IDs using a dedic
322308
- Injects `X-Correlation-ID` and `X-Causation-ID` headers from `ClientContextService` on every outgoing API request.
323309
- Attaches the JWT Bearer token.
324310
- Forwards the original browser's `User-Agent` and `X-Forwarded-For` IP from `IHttpContextAccessor`.
325-
- After each response: reads `X-Event-ID` from the response headers and calls `ClientContextService.UpdateCausationId(eventId)`, automatically advancing the causation chain.
311+
- After each response: attempts to read `X-Event-ID` and update `ClientContextService` when present.
326312
- On HTTP 401: clears stored tokens.
327313

328314
3. **`BookStoreHeaderHandler`** (`src/BookStore.Client/Infrastructure/BookStoreHeaderHandler.cs`):
@@ -339,11 +325,23 @@ The Blazor frontend automatically manages and propagates these IDs using a dedic
339325
ResilienceHandler → AuthorizationMessageHandler → TenantHeaderHandler → BookStoreHeaderHandler → HttpClientHandler
340326
```
341327

328+
### Blazor Web Frontend Logging
329+
330+
The Blazor frontend enriches logs with correlation and causation identifiers in both HTTP and SignalR flows:
331+
332+
1. **`LogEnrichmentMiddleware`** (`src/BookStore.Web/Infrastructure/LogEnrichmentMiddleware.cs`):
333+
- Registered via `app.UseMiddleware<LogEnrichmentMiddleware>()` in `Program.cs`.
334+
- Adds a structured scope with `CorrelationId`, `CausationId`, `TenantId`, and browser metadata.
335+
336+
2. **`LoggingHubFilter`** (`src/BookStore.Web/Infrastructure/LoggingHubFilter.cs`):
337+
- Registered as `IHubFilter` for Blazor Server SignalR hub invocations.
338+
- Adds the same tracing scope for component-triggered real-time operations.
339+
342340
## Summary
343341

344342
- **Correlation ID**: Tracks the entire business workflow
345343
- **Causation ID**: Tracks immediate event causes
346344
- **Event ID**: Unique identifier for each event
347-
- **Headers**: `X-Correlation-ID`, `X-Causation-ID`, `X-Event-ID`
345+
- **Headers**: `X-Correlation-ID`, `X-Causation-ID`
348346
- **Automatic**: System generates `Guid.CreateVersion7()` IDs if not provided
349-
- **Propagation**: `X-Correlation-ID` always returned in response headers; `X-Event-ID` returned when an endpoint appends an event
347+
- **Propagation**: `X-Correlation-ID` is echoed in responses; causation chaining can use upstream IDs and SSE event identifiers

0 commit comments

Comments
 (0)