> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Request ID

> Request ID generation and propagation middleware for tracing.

## Overview

The `requestid` middleware generates or propagates unique request IDs for distributed tracing and debugging. Each request gets a unique identifier that can be logged and passed to downstream services.

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/requestid"
```

## Quick Start

```go theme={null}
app := mizu.New()
app.Use(requestid.New())
```

## Configuration

| Option      | Type            | Default          | Description           |
| ----------- | --------------- | ---------------- | --------------------- |
| `Header`    | `string`        | `"X-Request-ID"` | Header name           |
| `Generator` | `func() string` | UUID v4          | ID generator function |

## Examples

### Basic Usage

```go theme={null}
app.Use(requestid.New())

app.Get("/", func(c *mizu.Ctx) error {
    id := requestid.Get(c)
    c.Logger().Info("processing", "request_id", id)
    return c.JSON(200, map[string]string{"id": id})
})
```

### Custom Header

```go theme={null}
app.Use(requestid.WithOptions(requestid.Options{
    Header: "X-Trace-ID",
}))
```

### Custom Generator

```go theme={null}
var counter uint64

app.Use(requestid.WithOptions(requestid.Options{
    Generator: func() string {
        return fmt.Sprintf("req-%d-%d", time.Now().Unix(), atomic.AddUint64(&counter, 1))
    },
}))
```

### ID Propagation

If the incoming request has a request ID header, it's preserved:

```
Client → X-Request-ID: abc123 → Server
                              → Response X-Request-ID: abc123
```

If not, a new one is generated:

```
Client → (no header) → Server generates: xyz789
                    → Response X-Request-ID: xyz789
```

### Logging with Request ID

```go theme={null}
app.Use(requestid.New())

app.Get("/", func(c *mizu.Ctx) error {
    logger := c.Logger().With("request_id", requestid.Get(c))
    logger.Info("handling request")
    // ...
    return c.JSON(200, data)
})
```

### Pass to Downstream Services

```go theme={null}
func callService(c *mizu.Ctx) error {
    req, _ := http.NewRequest("GET", "http://service/api", nil)
    req.Header.Set("X-Request-ID", requestid.Get(c))
    // ...
}
```

## API Reference

```go theme={null}
func New() mizu.Middleware
func WithOptions(opts Options) mizu.Middleware
func FromContext(c *mizu.Ctx) string
func Get(c *mizu.Ctx) string  // Alias for FromContext
```

## Technical Details

### Implementation

The requestid middleware is implemented with the following key components:

* **Context Storage**: Request IDs are stored in the request context using a private `contextKey{}` struct type to prevent collisions
* **ID Generation**: Default generator creates UUID v4-style identifiers using crypto/rand for cryptographic randomness
* **Header Propagation**: The middleware checks for existing request IDs in incoming headers and preserves them, or generates new ones if absent
* **Response Headers**: Request IDs are automatically added to response headers for client visibility

### UUID v4 Format

The default generator produces IDs in the format: `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`

* Uses 16 random bytes from `crypto/rand`
* Version bits (byte 6): Set to `0x40` to indicate version 4
* Variant bits (byte 8): Set to `0x80` to indicate RFC 4122 variant 2
* Final format: 32 hexadecimal characters in 5 groups (8-4-4-4-12)

### Context Key Design

The middleware uses a private struct type as the context key:

```go theme={null}
type contextKey struct{}
```

This prevents accidental key collisions with other middleware or application code that might use string or integer keys.

### Flow

1. Extract request ID from incoming header (if present)
2. If no header, generate new ID using configured generator
3. Store ID in request context with private key
4. Set ID in response header
5. Continue to next handler

## Best Practices

* Add early in middleware chain
* Include in all logs
* Pass to downstream services
* Use for error correlation

## Testing

The middleware includes comprehensive test coverage for all functionality:

| Test Case                          | Description                                                      | Expected Behavior                                                                                                        |
| ---------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `TestNew/generates request ID`     | Tests default middleware behavior when no request ID is provided | Generates a new UUID v4-style request ID, stores it in context, and sets it in response header                           |
| `TestNew/uses existing request ID` | Tests ID propagation when client provides an existing request ID | Preserves the existing request ID from request header, stores it in context, and returns it in response header           |
| `TestWithOptions_CustomHeader`     | Tests custom header name configuration                           | Uses custom header name (e.g., "X-Correlation-ID") instead of default "X-Request-ID"                                     |
| `TestWithOptions_CustomGenerator`  | Tests custom ID generator function                               | Uses provided generator function to create sequential custom IDs instead of UUID v4 format                               |
| `TestGenerateID`                   | Tests default UUID v4 generator format and uniqueness            | Generates IDs in correct UUID v4 format (8-4-4-4-12), sets version 4 bit, and ensures uniqueness across 1000 generations |
| `TestGet`                          | Tests that Get() and FromContext() are equivalent                | Both functions return the same request ID value from context                                                             |

## Related Middlewares

* [timing](/middlewares/timing) - Performance tracing
* [recover](/middlewares/recover) - Panic recovery with context
