Skip to main content

Overview

The bodydump middleware captures and logs request and response bodies for debugging purposes. Use it when you need:
  • Debug API requests
  • Log request/response pairs
  • Troubleshoot integrations

Installation

import "github.com/go-mizu/mizu/middlewares/bodydump"

Quick Start

app := mizu.New()

app.Use(bodydump.New(func(c *mizu.Ctx, reqBody, resBody []byte) {
    log.Printf("Request: %s", reqBody)
    log.Printf("Response: %s", resBody)
}))

Configuration

Options

OptionTypeDefaultDescription
RequestbooltrueDump request body
ResponsebooltrueDump response body
MaxSizeint6464KBMax body size to capture
Handlerfunc(*mizu.Ctx, []byte, []byte)RequiredDump callback
SkipPaths[]stringnilPaths to skip
SkipContentTypes[]stringnilContent types to skip

Examples

Basic Logging

app.Use(bodydump.New(func(c *mizu.Ctx, req, res []byte) {
    log.Printf("[%s %s] Req: %s Res: %s",
        c.Request().Method,
        c.Request().URL.Path,
        req, res)
}))

Skip Large Bodies

app.Use(bodydump.WithOptions(bodydump.Options{
    Handler: dumpHandler,
    MaxSize: 1024, // Only dump first 1KB
}))

Skip Specific Paths

app.Use(bodydump.WithOptions(bodydump.Options{
    Handler:   dumpHandler,
    SkipPaths: []string{"/health", "/metrics"},
}))

Skip Content Types

app.Use(bodydump.WithOptions(bodydump.Options{
    Handler:          dumpHandler,
    SkipContentTypes: []string{"image/jpeg", "image/png"},
}))

Request Only

app.Use(bodydump.RequestOnly(func(c *mizu.Ctx, body []byte) {
    log.Printf("Request: %s", body)
}))

Response Only

app.Use(bodydump.ResponseOnly(func(c *mizu.Ctx, body []byte) {
    log.Printf("Response: %s", body)
}))

JSON Formatting

app.Use(bodydump.New(func(c *mizu.Ctx, req, res []byte) {
    entry := map[string]any{
        "method":   c.Request().Method,
        "path":     c.Request().URL.Path,
        "request":  string(req),
        "response": string(res),
    }
    json.NewEncoder(os.Stdout).Encode(entry)
}))

API Reference

Functions

// New creates body dump middleware
func New(handler func(*mizu.Ctx, []byte, []byte)) mizu.Middleware

// WithOptions creates with configuration
func WithOptions(opts Options) mizu.Middleware

// RequestOnly dumps only request bodies
func RequestOnly(handler func(*mizu.Ctx, []byte)) mizu.Middleware

// ResponseOnly dumps only response bodies
func ResponseOnly(handler func(*mizu.Ctx, []byte)) mizu.Middleware

Technical Details

Implementation Overview

The bodydump middleware uses a capture mechanism to intercept and store request/response bodies:
  1. Request Body Capture: Reads the request body using io.LimitReader to respect the MaxSize limit, then restores it using io.NopCloser with a bytes reader so downstream handlers can still access it.
  2. Response Body Capture: Implements a custom responseCapture wrapper that implements http.ResponseWriter. It intercepts Write() calls to capture the response body up to the configured MaxSize while still writing to the original response writer.
  3. Filtering Mechanisms:
    • Path Filtering: Uses a map lookup for O(1) skip path checks
    • Content-Type Filtering: Skips configured content types to avoid dumping binary data
    • Size Limiting: Enforces maximum capture size on both request (via io.LimitReader) and response (via byte counting)

Default Values

  • MaxSize: 64KB (65,536 bytes)
  • Request: true (enabled)
  • Response: true (enabled)

Performance Considerations

  • Path and content-type skipping uses hash maps for efficient lookups
  • Body capture is limited by MaxSize to prevent memory issues
  • Request body is read once and restored for handler use
  • Response capture adds minimal overhead as it writes through to the original writer

Security Warning

Body dump may capture sensitive data. Never use in production without proper filtering.

Best Practices

  • Only enable in development/debugging
  • Filter sensitive data
  • Set reasonable size limits
  • Skip high-volume endpoints

Testing

The bodydump middleware includes comprehensive test coverage for all major functionality:
Test CaseDescriptionExpected Behavior
TestNewBasic middleware creation with default optionsCaptures both request and response bodies correctly
TestWithOptions_RequestOnlyRequest-only dumping configurationDumps only request body, response body is empty
TestWithOptions_ResponseOnlyResponse-only dumping configurationDumps only response body, request body is empty
TestWithOptions_MaxSizeMaximum size limit enforcementRequest body is truncated to MaxSize bytes (5 bytes in test)
TestWithOptions_SkipPathsPath skipping functionalityHandler is not called for paths in SkipPaths array
TestRequestOnlyRequestOnly helper functionCaptures only request body using simplified API
TestResponseOnlyResponseOnly helper functionCaptures only response body using simplified API
TestBodyPreservedRequest body preservationRequest body remains readable by downstream handlers after dumping