# Story 12.1: FastAPI request_id Logging (Correlation ID Middleware, Concurrency-Safe)

**Status:** Complete
**Priority:** P0 (High)
**Depends on:** None
**Epic:** 12.0 Cookbook (SEO-Driven Documentation)

---

## Context / Background

"FastAPI request id logging" and "FastAPI correlation id middleware" are among the most searched logging queries. Developers hit concurrency issues where request IDs "overlap" or appear in wrong requests when they don't use async context correctly.

fapilog solves this with built-in context propagation that is concurrency-safe by design.

**Target search queries:**

- "FastAPI request id logging"
- "FastAPI correlation id middleware"
- "request ids overlapped fastapi"
- "python async context logging"

**Why fapilog is the answer:** Built-in context variables that propagate correctly across async boundaries without manual threading.local() hacks.

---

## Scope (In / Out)

### In Scope

- Cookbook page explaining the concurrency problem
- Minimal middleware setup snippet
- How to access request_id in deeper application layers
- Explanation of why IDs overlap and how fapilog avoids it

### Out of Scope

- Full middleware implementation (link to existing docs)
- Distributed tracing integration (separate cookbook page)
- Custom ID generation strategies

---

## Acceptance Criteria

### AC1: Page Exists with Correct Title

**Description:** Cookbook page created with SEO-optimized title.

**Validation:**
```
docs/cookbook/fastapi-request-id-logging.md exists
H1: "FastAPI request_id logging (correlation ID middleware, concurrency-safe)"
```

### AC2: Problem Section Explains Concurrency Issue

**Description:** Clear explanation of why naive approaches fail.

**Validation:**
- Describes the "overlapping IDs" problem
- Shows why threading.local() doesn't work with async
- References real pain points from Stack Overflow

### AC3: Solution Shows Minimal Working Code

**Description:** Copy-pasteable example that works.

**Validation:**
```python
from fastapi import FastAPI, Depends
from fapilog.fastapi import setup_logging, get_request_logger

lifespan = setup_logging()
app = FastAPI(lifespan=lifespan)

@app.get("/")
async def root(logger=Depends(get_request_logger)):
    logger.info("request_id is automatically included")
```

### AC4: Deep Access Pattern Documented

**Description:** Shows how to access request_id in service/repository layers.

**Validation:**
- Example of getting request_id outside of route handlers
- Pattern for passing context to sync code if needed

### AC5: Why It Works Section

**Description:** Brief technical explanation of fapilog's approach.

**Validation:**
- Mentions contextvars (not threading.local)
- Explains automatic propagation across await boundaries

---

## Implementation Notes

### File Path

`docs/cookbook/fastapi-request-id-logging.md`

### Page Structure

```markdown
# FastAPI request_id logging (correlation ID middleware, concurrency-safe)

Every request needs a unique ID for tracing...

## The Problem: Overlapping Request IDs

{Code showing the wrong way}
{Explanation of why it fails under concurrency}

## The Solution

{Minimal fapilog setup}

## Accessing request_id in Deeper Layers

{Pattern for services/repositories}

## Why This Works (Technical Detail)

{Brief explanation of contextvars}

## Going Deeper

- [FastAPI Integration Guide](/guides/fastapi)
- [Context Propagation Reference](/api-reference/context)
```

---

## Tasks

- [x] Create `docs/cookbook/fastapi-request-id-logging.md`
- [x] Write problem section with concurrency explanation
- [x] Write solution section with working code
- [x] Write deep access pattern section
- [x] Write technical explanation section
- [x] Add cross-links to related docs
- [x] Test code examples work

---

## Tests

- Code examples compile and run
- Links to other docs are valid
- Page renders correctly in docs build

---

## Definition of Done

### Content Complete

- [x] All sections written per template
- [x] Code examples tested
- [x] Technical accuracy verified

### SEO Optimized

- [x] Target keywords in H1
- [x] Target keywords in first paragraph
- [x] Page under 1000 words

### Integrated

- [x] Added to cookbook index
- [x] Cross-linked from FastAPI guide

---

## Risks / Rollback

### Risks

1. **Risk:** API changes break code examples
   - **Mitigation:** Add to docs test suite

### Rollback Plan

Revert commit if issues found.

---

---

## Code Review

**Date:** 2026-01-21
**Reviewer:** Claude
**Verdict:** OK to PR

### Summary

Reviewed cookbook page for FastAPI request_id logging covering concurrency-safe correlation ID middleware using contextvars.

### AC Verification

| Criterion | Evidence |
|-----------|----------|
| AC1: Page exists with correct title | `docs/cookbook/fastapi-request-id-logging.md:1` - H1 matches exactly |
| AC2: Problem section explains concurrency | `docs/cookbook/fastapi-request-id-logging.md:5-37` - threading.local() failure, symptoms, SO reference |
| AC3: Solution shows minimal working code | `docs/cookbook/fastapi-request-id-logging.md:43-54` - exact match to validation snippet |
| AC4: Deep access pattern documented | `docs/cookbook/fastapi-request-id-logging.md:64-102` - service layer + sync code patterns |
| AC5: Why it works section | `docs/cookbook/fastapi-request-id-logging.md:104-128` - contextvars, PEP 567, propagation explained |

### Quality Gates

- [x] Docs build passed
- [x] All links valid
- [x] Code examples verified against actual API
- [x] Word count under 1000 (556 words)

---

## Change Log

| Date | Change | Author |
|------|--------|--------|
| 2026-01-21 | Initial draft | Claude |
| 2026-01-21 | Implementation complete | Claude |
| 2026-01-21 | Code review passed | Claude |
