requestid

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

RequestID

Go Reference Go Version License

Give every request a unique ID. You can use it in logs and across services to trace a single request from start to finish.

Full docs: Middleware Guide and Middleware Reference.

Features

  • Generates a unique ID per request (UUID v7 by default, or ULID)
  • Uses the client's X-Request-ID if they send one (good for tracing)
  • Puts the ID in the response header so clients can log it
  • Short option: ULID (26 chars) instead of UUID (36 chars)
  • Custom header name and custom ID generator supported

Installation

go get rivaas.dev/middleware/requestid

Requires Go 1.25 or later.

Quick Start

package main

import (
    "net/http"
    "rivaas.dev/router"
    "rivaas.dev/middleware/requestid"
)

func main() {
    r := router.New()
    r.Use(requestid.New())

    r.GET("/", func(c *router.Context) {
        id := requestid.Get(c)
        c.JSON(http.StatusOK, map[string]string{
            "request_id": id,
        })
    })

    http.ListenAndServe(":8080", r)
}

Register requestid early so the ID is available to accesslog and other middleware.

Configuration

Option What it does
WithHeader Header name for request ID (default: X-Request-ID)
WithULID Use ULID instead of UUID v7 (shorter IDs)
WithGenerator Your own function to generate IDs
WithAllowClientID Whether to accept an ID from the client (default: true)

Use ULID for shorter IDs:

r.Use(requestid.New(requestid.WithULID()))

Custom header:

r.Use(requestid.New(requestid.WithHeader("X-Trace-ID")))

Getting the ID in handlers

id := requestid.Get(c)
logger.Info("processing request", "request_id", id, "path", c.Request.URL.Path)

Examples

A runnable example is in the example/ directory:

cd example
go run main.go

Check the response headers for X-Request-ID.

Learn More

License

Apache License 2.0 – see LICENSE for details.

Documentation

Overview

Package requestid provides middleware for generating and tracking request IDs for distributed tracing and correlation.

This middleware generates unique request IDs for each HTTP request and stores them in the request context. The ID is also included in response headers, allowing clients to correlate requests across services in distributed systems.

Basic Usage

import "rivaas.dev/middleware/requestid"

r := router.MustNew()
r.Use(requestid.New())

Request ID Generation

By default, UUID v7 is used for request ID generation. UUID v7 is time-ordered and lexicographically sortable (RFC 9562), making it ideal for debugging and log correlation. Generated IDs are 36-character UUID strings.

The middleware generates request IDs using:

  • X-Request-ID header: Uses existing header if present (for request tracing)
  • UUID v7 generation: Time-ordered UUID if no header present (default)
  • ULID generation: Compact 26-character alternative via WithULID

ID Format Comparison

  • UUID v7 (default): 018f3e9a-1b2c-7def-8000-abcdef123456 (36 chars)
  • ULID: 01ARZ3NDEKTSV4RRFFQ69G5FAV (26 chars)

Configuration Options

  • WithHeader: Custom header name for request ID (default: X-Request-ID)
  • WithULID: Use ULID instead of UUID v7 for shorter IDs
  • WithGenerator: Custom function for generating request IDs
  • WithAllowClientID: Control whether to accept client-provided IDs

Using ULID

For shorter request IDs, use ULID:

r.Use(requestid.New(requestid.WithULID()))

Accessing Request ID

The request ID is stored in the request context and can be retrieved:

import "rivaas.dev/middleware/requestid"

func handler(c *router.Context) {
    id := requestid.Get(c)
    // Use id for logging, tracing, etc.
}

Response Headers

The middleware automatically includes the request ID in response headers, allowing clients to track requests across services.

Integration with Logging

Request IDs are commonly used with structured logging for request correlation:

logger.Info("processing request",
    "request_id", requestid.Get(c),
    "method", c.Request.Method,
    "path", c.Request.URL.Path,
)

Package requestid provides middleware for generating and managing unique request IDs for distributed tracing and request correlation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Get

func Get(c *router.Context) string

Get retrieves the request ID from the context. Returns an empty string if no request ID has been set.

Example:

func handler(c *router.Context) {
    requestID := requestid.Get(c)
    log.Printf("Processing request %s", requestID)
}

func New

func New(opts ...Option) router.HandlerFunc

New returns a middleware that adds a unique request ID to each request. The request ID can be used for distributed tracing and log correlation.

By default, UUID v7 is used for request ID generation. UUID v7 is time-ordered and lexicographically sortable (RFC 9562), making it ideal for debugging and log correlation.

The middleware will: 1. Check if a request ID is already present in the configured header 2. Use the existing ID if allowed, or generate a new one 3. Set the request ID in the response header

Basic usage (UUID v7 by default):

r := router.MustNew()
r.Use(requestid.New())

Using ULID (shorter, 26 characters):

r.Use(requestid.New(requestid.WithULID()))

Custom header name:

r.Use(requestid.New(
    requestid.WithHeader("X-Correlation-ID"),
))

Custom generator:

r.Use(requestid.New(
    requestid.WithGenerator(func() string {
        return fmt.Sprintf("req-%d", time.Now().UnixNano())
    }),
))

Disable client IDs:

r.Use(requestid.New(
    requestid.WithAllowClientID(false),
))

Accessing the request ID in handlers:

r.GET("/users/:id", func(c *router.Context) {
    requestID := c.Response.Header().Get("X-Request-ID")
    // Use requestID for logging, tracing, etc.
})

Types

type Option

type Option func(*config)

Option defines functional options for requestid middleware configuration.

func WithAllowClientID

func WithAllowClientID(allow bool) Option

WithAllowClientID controls whether to accept request IDs from clients. When true, if the client provides a request ID in the header, it will be used. When false, always generate a new request ID regardless of client input. Default: true

Security note: Set to false if you need to ensure all request IDs are server-generated.

Example:

requestid.New(requestid.WithAllowClientID(false))

func WithGenerator

func WithGenerator(generator func() string) Option

WithGenerator sets a custom function to generate request IDs. The generator function should return a unique string for each call.

By default, UUID v7 is used (time-ordered, RFC 9562 compliant). Use this option when you need a custom format.

Example with custom format:

requestid.New(requestid.WithGenerator(func() string {
    return fmt.Sprintf("req-%d-%s", time.Now().Unix(), randomString(8))
}))

func WithHeader

func WithHeader(headerName string) Option

WithHeader sets the header name for the request ID. Default: "X-Request-ID"

Example:

requestid.New(requestid.WithHeader("X-Trace-ID"))

func WithULID

func WithULID() Option

WithULID uses ULID for request ID generation instead of UUID v7. ULID provides time-ordered, lexicographically sortable identifiers with a compact 26-character representation.

ULID format: 01ARZ3NDEKTSV4RRFFQ69G5FAV (26 characters) UUID v7 format: 018f3e9a-1b2c-7def-8000-abcdef123456 (36 characters)

Use ULID when you need shorter IDs or case-insensitive identifiers.

Example:

requestid.New(requestid.WithULID())

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL