Overview
Add unique IDs to each request for distributed tracing. Propagates IDs to downstream services.
Features
- UUID generation
- Header propagation
- Correlation context creation
- Incoming ID respect
- X-Request-Id and X-Correlation-Id headers
Installation
npx hanma add fastify-request-id --framework fastify
Dependencies
fastify
Code
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
import crypto from "crypto";
/**
* Request ID configuration
*/
interface RequestIdConfig {
headerName?: string;
prefix?: string;
generator?: () => string;
}
const defaultConfig: RequestIdConfig = {
headerName: "x-request-id",
prefix: "req",
generator: () => crypto.randomUUID(),
};
/**
* Generate a unique request ID
*/
export function generateRequestId(prefix = "req"): string {
return `${prefix}_${Date.now()}_${crypto.randomBytes(8).toString("hex")}`;
}
/**
* Register request ID handling
* - Uses incoming request ID if present
* - Generates new ID if not
* - Adds ID to response headers
* - Adds ID to log context
*/
export function registerRequestId(
app: FastifyInstance,
config?: RequestIdConfig
): void {
const { headerName, prefix, generator } = { ...defaultConfig, ...config };
// Add request ID before routing
app.addHook("onRequest", async (request: FastifyRequest, reply: FastifyReply) => {
// Use existing ID from header or generate new one
const existingId = request.headers[headerName!] as string | undefined;
const requestId = existingId ?? generator!();
// Store on request for access in handlers
(request as any).requestId = requestId;
// Add to response headers
reply.header(headerName!, requestId);
reply.header("x-correlation-id", requestId);
});
}
/**
* Get request ID from request object
*/
export function getRequestId(request: FastifyRequest): string {
return (request as any).requestId ?? request.id;
}
/**
* Create a correlation context for propagating request ID to downstream services
*/
export function createCorrelationHeaders(request: FastifyRequest): Record<string, string> {
const requestId = getRequestId(request);
return {
"x-request-id": requestId,
"x-correlation-id": requestId,
"x-trace-id": requestId,
};
}
/**
* Middleware to require request ID (for services that should always receive one)
*/
export async function requireRequestId(
request: FastifyRequest,
reply: FastifyReply
): Promise<void> {
const headerName = "x-request-id";
const requestId = request.headers[headerName];
if (!requestId) {
reply.status(400).send({
error: "Bad Request",
message: `Missing required header: ${headerName}`,
});
}
}
// Usage:
// registerRequestId(app);
//
// In handlers:
// const requestId = getRequestId(request);
//
// For downstream calls:
// fetch(url, { headers: createCorrelationHeaders(request) });
Usage
import { registerRequestId, getRequestId, createCorrelationHeaders } from './utils/request-id';
registerRequestId(app);
// In handlers:
const requestId = getRequestId(request);
// For downstream calls:
fetch(url, { headers: createCorrelationHeaders(request) });
Dependencies
fastify
Frequently Asked Questions
How do I install Request ID?
Run the following command:
npx hanma add fastify-request-id --framework fastifyWhat dependencies are required?
This snippet requires: fastify. Make sure to install them before using the snippet.
How do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to
src/utils/request-id.ts.Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.