@cogs/serialize-request
v0.2.0
Published
A utility function to serialize a request object in a way that's friendly to loggers, view engines, and converting to JSON
Readme
@cogs/serialize-request
Utility helpers for turning any inbound request into a logger-friendly JSON snapshot. Works with Next.js Request objects, the standard Fetch API Request, Node's IncomingMessage, or plain objects you shape yourself. The snapshotter normalizes IDs, methods, URLs, headers, and route metadata so observability pipelines receive a consistent payload regardless of runtime.
Why it exists
- Predictable log payloads – Normalize
x-request-id, uppercase methods, and trim long URLs so structured logs stay readable. - Header safety – Only include headers from a configurable allowlist (ignoring cookies/authorization by default) or pass an explicit whitelist for sensitive APIs.
- Route + params support – Serializes
route.path/paramsshapes used by Next middleware/route handlers without extra glue code. - Primitive fallback – If you pass a string/number/boolean, it still returns a well-formed
{ id, method, url, headers }object.
Anywhere you currently hand-build request metadata—middleware, API routes, instrumentation hooks, worker crash handlers—you can drop in serializeRequest() and ship an identical JSON shape.
import serializeRequest from "@cogs/serialize-request"
const serialized = serializeRequest(request, {
includeHeaders: ["x-request-id", "user-agent", "content-type"],
})
log.info("middleware handling request", {
request: serialized,
routeType,
isAuthenticated: request.auth != null && request.auth.error == null,
})Adding that ahead of your existing log calls yields consistent payloads:
{
"request": {
"id": "abc123",
"method": "GET",
"url": "/environments/42",
"headers": {
"x-request-id": "abc123",
"user-agent": "…",
"content-type": "application/json"
},
"route": {
"path": "/api/environments/[id]",
"params": { "id": "42" }
}
},
"routeType": "api",
"isAuthenticated": true
}No more duplicating header filtering or ID extraction; just call the helper and log the request field wherever you need it.
API surface
serializeRequest(request, options?)
Returns a normalized snapshot:
id– resolved fromx-request-idheader (ornullif absent).method– uppercased string, falls back to"-".url– path + query, truncated when it grows unwieldy (default 200 characters).headers– subset of allowed headers; defaults to a safe internal list and can be overridden viaincludeHeaders.route–{ path, params }when those properties exist on the incoming object (useful for Next'sroutemetadata).
Options:
includeHeaders?: string[]– additional header names to whitelist. Values are normalized to lowercase internally.
Observability helpers
The package also exports helpers that pair neatly with loggers:
captureRequestSnapshot(request, options?)– RunsserializeRequest()(merging the built-in headers with the inlined safe-meta-header allowlist) and caches the snapshot onglobalThis. Returns the serialized object so you can log it immediately.getLastRequestSnapshot()– Read the most recently captured snapshot (used by crash handlers to include request metadata in fatal logs).REQUEST_SNAPSHOT_HEADER_WHITELIST– Read-only list of headers captured by default, useful for documentation or downstream validation.
Usage ideas
- Middleware logging – replace ad-hoc header lookups with
captureRequestSnapshot()to ensure every info/warn/error has identical request metadata. - API routes – call
const logBase = { request: captureRequestSnapshot(request) }once and spread it into every logger call. - Crash handlers – call
captureRequestSnapshot()when a request enters your system; later, usegetLastRequestSnapshot()insideuncaughtExceptionandunhandledRejectionlisteners to add the context automatically. - View engines / SSR – pass the serialized object into your template renderer or monitoring hooks without worrying about non-serializable headers.
