Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Request Id Laravel Package

snowflake/request-id

Laravel package that attaches a unique request ID to every incoming request, exposes it through response headers and a helper, and makes it available to logs so you can trace, correlate, and debug requests across services and distributed systems.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is a Symfony bundle, not a Laravel package. snowflake/request-id ships a Symfony Bundle subclass, a kernel event subscriber, and a Configuration.php tree consumed by Symfony's DI container. Laravel will not auto-discover it, and its service definitions (services.yaml, tagged subscribers, kernel.request priority) mean nothing to Laravel's container. If your day job is Laravel, treat this repo as reference source code to copy from, not as a dependency to composer require.

Where to look, in order:

  1. composer.json — confirm the type (symfony-bundle) and the require block. If it pins symfony/http-kernel with a tight constraint, assume it will not survive an upgrade.
  2. src/ — find the event subscriber (usually on kernel.request). That single file is the entire feature: read the request ID from an inbound header, generate a UUID if absent, mutate the Request headers, then re-attach on kernel.response.
  3. DependencyInjection/Configuration.php — the real option names live here (header name, whether to trust an inbound header, whether to emit a response header). Do not guess config keys from the README.
  4. tests/ — with zero stars and zero dependents, the test suite is your only spec. If it is absent or trivial, budget for reading the subscriber line by line.

First use case for a Laravel developer: stop guessing which log line belongs to which failing checkout. You want every request to carry an ID that appears in (a) the response header so the frontend/QA can quote it, and (b) every Log:: call. In Laravel that is a 20-line middleware plus a log context push — see below. Only reach for this bundle's code if you are actually on Symfony.

Minimum viable Laravel equivalent (copy the behavior, not the code):

// app/Http/Middleware/RequestId.php
public function handle($request, Closure $next)
{
    $id = $request->header('X-Request-Id') ?: (string) Str::uuid();
    $request->headers->set('X-Request-Id', $id);
    Log::withContext(['request_id' => $id]);

    return $next($request)->header('X-Request-Id', $id);
}

Register it globally in bootstrap/app.php (Laravel 11+) so it runs before auth and validation logging.

Implementation Patterns

Middleware-first, everywhere. The pattern this package encodes is: one early middleware establishes identity, all downstream layers read it and never mint their own. Enforce that with a helper (request_id()) rather than sprinkling $request->header(...) around — otherwise one missing header on a queued-job-triggered path gives you two IDs for one logical operation.

Propagate to async work. The highest-value integration is carrying the ID across boundaries:

  • Queued jobs — capture at dispatch and re-apply in the job so Horizon/Failed-jobs logs correlate to the originating request. In Laravel, Log::withContext() does not survive a serialized job; push the ID onto the job payload explicitly.
  • Outbound HTTP — attach X-Request-Id in a Guzzle middleware or Http::withHeaders() global macro so a downstream service (and its logs) share the same ID. This is how you get end-to-end tracing without a full OpenTelemetry rollout.
  • Scheduled commands — there is no request, so generate a deterministic-ish ID per run (command-name + timestamp) rather than reusing this bundle's request path.

Trust policy is a decision, not a default. Accepting an inbound X-Request-Id lets an upstream gateway set correlation — good behind a load balancer you control. It also lets any anonymous client forge it, poisoning your logs and making two unrelated requests look like one. Decide explicitly: accept only from known proxies (Laravel TrustProxies), or always regenerate and emit your own. Most teams should regenerate at the edge and only trust internally.

Response header for support workflows. Echoing the ID back means a user can screenshot an error page, and support can grep the ID straight to the log line. Pair it with a custom error view that surfaces it — the header alone is invisible to users.

Log processor vs. manual context. In Symfony you would register a Monolog processor that reads the current request. In Laravel the Log::withContext() call in middleware is the equivalent and is enough for the vast majority of apps; a Monolog processor is only worth it if you have non-HTTP code that needs the same ID injected.

Gotchas and Tips

Framework mismatch is the headline risk. Zero stars, zero dependents, and a Symfony-only shape means: no CVE response, no Laravel adapter, and no community answer if the subscriber conflicts with another kernel.request listener. Treat it as a recipe. If you genuinely need this on Symfony, verify it against your Symfony version before committing — kernel.request priorities and the Bundle class signature have moved across majors.

Header case and normalization. HTTP headers are case-insensitive, but $request->header('X-Request-Id') and $request->headers->get('x-request-id') can behave differently depending on the stack, and proxies love to rewrite casing. Normalize once, and be consistent in logs. Also watch for whitespace and absurdly long values in inbound headers — validate length (e.g. ≤ 128 chars) and charset before you accept a client-supplied ID, or you invite log injection (CRLF in a header that ends up in a log file).

Duplicate IDs from retries and sub-requests. Symfony sub-requests and Laravel's internal $this->call() testing helper both re-enter middleware. Guard against minting a fresh ID on re-entry, otherwise a single user action produces a tree of unrelated IDs. Same for queue retries — the same job carrying the same ID across three attempts is a feature; three different IDs is a debugging nightmare.

Ordering matters. Register the middleware first in the global stack. If it runs after error handling is configured, exceptions thrown during boot (bad route binding, container errors) get logged with no ID — exactly the requests you care about most.

Cost of UUID generation is irrelevant; cost of logging the wrong thing is not. Don't stop at the header — verify the ID actually lands in your log lines. The classic failure mode is "we added the middleware, but our custom log channel doesn't get Log::withContext because it uses a separate Monolog stack." Test by throwing a 500 and grepping the log.

Extension points, if you do fork it. The clean seams are (a) the ID generator — swap UUIDv4 for ULID or a Snowflake if you want sortable IDs, which pairs well with time-ordered log queries; (b) the header name; (c) the trust policy. Everything else is boilerplate and should stay untouched, which keeps the diff small enough to re-apply after a future Symfony upgrade.

When not to use it. If you already run OpenTelemetry, Sentry, or a service mesh with trace propagation, a bespoke request-ID header duplicates trace_id and will drift from it. Use one identifier, or explicitly map the request ID to the trace ID at the edge. Two competing correlation IDs is worse than none.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource