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

Symfony Route Deprecation Bundle Laravel Package

halloverden/symfony-route-deprecation-bundle

A Symfony bundle for deprecating routes: mark routes as deprecated so requests trigger configurable deprecation notices, helping you track usage and migrate consumers safely before removal.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package, so the first step is acknowledging the framework boundary: you can evaluate it, but you cannot composer require it into a Laravel app and expect it to work without adaptation. For a Symfony service, the minimal path is:

  1. composer require halloverden/symfony-route-deprecation-bundle
  2. Register the bundle in config/bundles.php (Symfony 5.4+/6+ auto-registration may not apply; check the README).
  3. If the bundle exposes configuration, add a config/packages/route_deprecation.yaml entry — read the bundle's DependencyInjection/Configuration.php first; with only 9 stars, the README may lag behind the code.
  4. Look first at the bundle's EventListener/EventSubscriber class. That is where the Deprecation header is injected, and it tells you exactly which routes and which responses are affected.

The first real use case: you have a legacy /api/v1/... endpoint that still receives traffic, and you want to advertise its deprecation to clients in-band rather than only in release notes. The value of the package is that it implements the IETF Deprecation HTTP header draft (a structured-field timestamp, optionally with a link to migration docs), so clients and API gateways can discover deprecation programmatically instead of via email.

A minimal illustrative controller usage (confirm the exact attribute name against the source):

#[Route('/api/v1/orders', name: 'api_v1_orders')]
#[Deprecated(since: '2024-01-01', link: 'https://docs.example.com/migrate/v2')]
public function legacyOrders(): Response
{
    // ...
}

Verify with curl -I https://app.test/api/v1/orders and look for the Deprecation: response header before building anything on top of it.

Implementation Patterns

Attribute-per-action. The natural pattern is annotating individual controller actions or classes. This keeps the deprecation next to the code it applies to and survives route renames better than a central config list. Prefer this for a handful of endpoints.

Route-default / config-driven. If deprecation is driven by API version (everything under /v1), a listener that inspects the matched route name or path prefix is less repetitive than dozens of attributes. The bundle likely exposes route defaults or a config map; if not, a small custom subscriber on kernel.response that reads $request->attributes->get('_route') is a ten-line extension.

Deprecation + Sunset together. The Deprecation header says "this is deprecated"; RFC 8594's Sunset says "it will stop working on date X." Use both. If the bundle only sets Deprecation, add Sunset in the same subscriber — clients need the deadline to act.

Versioned API rollout. Deprecate v1 while v2 is live; run both for a bake period; monitor which clients still hit v1 (log User-Agent / API key on deprecated routes); then remove. The header is the announcement channel; your access logs are the enforcement channel.

Documentation and SDK integration. Point the link parameter at the migration guide, not the changelog. If you publish OpenAPI, mirror the deprecation there (deprecated: true) so generated SDKs surface it — the HTTP header and the spec should not disagree.

Testing. In Symfony's KernelBrowser/WebTestCase, assert on $client->getResponse()->headers->get('Deprecation') for a deprecated route and assert its absence for a current one. Add a test that fails if a route marked deprecated has no link.

Laravel analogue, for comparison. In Laravel you would implement the same behavior as route middleware or a global middleware reading $request->route()->getName(), appending headers in $next($request) — there is no equivalent package dependency to take on. This is worth noting if your team is evaluating whether to port the idea rather than the bundle.

Gotchas and Tips

  • Maturity risk. 9 stars, 0 dependents, single-maintainer risk. Pin an exact version, read the listener source before trusting it, and be prepared to vendor/fork. The concept is more valuable than the implementation.
  • Header may be stripped in transit. CDNs, API gateways, and some reverse proxies drop unknown response headers. Verify end-to-end through your actual edge, not just against the Symfony dev server.
  • HTTP caching. If responses are cached (Symfony HttpCache, Varnish, Cloudflare), the header must be present on the cached representation or added by the edge. A kernel.response listener runs before kernel.terminate, but cache hits served by a proxy never reach PHP.
  • Structured-field syntax. The draft uses RFC 8941 structured fields (e.g. @1688169599). If you hand-roll the header elsewhere, don't emit a bare ISO date — clients parsing per spec will reject or misread it.
  • Not the same as PHP deprecations. trigger_deprecation() and @deprecated are for code-level notices; this is an HTTP contract with API consumers. Don't conflate them in docs.
  • Listener priority conflicts. If other subscribers also touch response headers, or if you have a CORS listener, check ordering. A low-priority subscriber can be overwritten by later header manipulation.
  • Route matching edge cases. Redirects, 404s, HEAD requests, and sub-requests may or may not get the header depending on how the bundle resolves the route. Test each; undefined behavior here is common in small bundles.
  • Extension points to lean on. The cleanest fallback if the bundle is too narrow: a single EventSubscriberInterface on kernel.response with a route-name→metadata map. You keep the spec-compliant header format and drop the dependency.
  • Client-side reality. Most HTTP clients ignore Deprecation. Pair the header with response-body warnings or a Warning header if you need humans to notice, and with account-manager outreach for high-value integrations.
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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel