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

Framework Extra Bundle Laravel Package

jungi/framework-extra-bundle

A Symfony bundle that adds extra annotations and conveniences beyond SensioFrameworkExtraBundle, helping streamline controller configuration and common framework tasks with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. This is a Symfony bundle, not a Laravel package. There is no service provider, no config/ publish tag, and Composer will not auto-register anything in a Laravel app. Treat this assessment as: (a) how to use it if your team also runs Symfony services, and (b) which patterns are worth stealing for a Laravel codebase.

  1. Confirm the target runtime. v2.1.0 moved every value argument resolver onto Symfony's ValueResolverInterface, which only exists from Symfony 6.2. That effectively raises the floor: treat 6.2+ as the supported range and do not assume 5.4 still works without pinning an older tag. If you are 100% Laravel, skip to the exit-strategy note in Gotchas — the same problems are already solved by FormRequest + middleware.
  2. Install and register in the Symfony host app:
    composer require jungi/framework-extra-bundle
    
    Then add it to config/bundles.php:
    Jungi\FrameworkExtraBundle\JungiFrameworkExtraBundle::class => ['all' => true],
    
  3. Look here first, in order:
    • The Attributes/ directory — this is the entire public surface. Everything the package does is driven by PHP 8 attributes on controller actions/methods.
    • The ValueResolver/ (argument resolver) classes and the DependencyInjection/ extension — as of v2.1.0 these implement ValueResolverInterface, which tells you both when attributes are read and how to override them, and the DI config tells you the tag/service ids.
    • The README's attribute reference table, if present. With zero dependents, the source is the documentation.
  4. First use case (Symfony side): annotate a controller action to (a) bind request data to typed parameters/DTOs and (b) declare the response content type so the bundle negotiates against the Accept header. In Laravel terms, that is the equivalent of replacing a FormRequest + response()->json() boilerplate pair with declarative method-level metadata.

First use case (Laravel side): read the attribute set as a design spec. The valuable idea is "request/response contract lives next to the handler, not in a separate FormRequest class or middleware file." You can reproduce this in Laravel with a custom Route::macro or a controller dispatcher that reflects over method attributes.

Implementation Patterns

Symfony host application

  • Request binding: keep attributes on the controller action thin — map query/body/file inputs into typed scalars or a DTO, and let Symfony's Validator handle constraints on the DTO. Do not put business rules in the attribute arguments.
  • Content negotiation: declare produces/consumes at the action level, then let the bundle resolve Accept/Content-Type. Pair this with a serializer so negotiation and serialization don't drift. If a controller accepts application/vnd.api+json, the vendor media type has to be declared explicitly — the negotiator will not guess it from application/json.
  • Response operations: use attributes to set status/headers on the happy path; keep error responses in exception listeners. Mixing "attribute sets status" and "listener mutates the same response" is where surprises come from.
  • Composition with Symfony's own features: this bundle predates #[MapRequestPayload] and #[MapQueryString] (Symfony 6.3+). Do not enable both resolution mechanisms across the same controller set; pick one per bounded context. Note that the v2.1.0 change puts this bundle's resolvers in the same pipeline as Symfony's native ones, so the "pick one" rule now matters operationally, not just stylistically.
  • Pinning: with the resolver interface change landing in a minor version, use "jungi/framework-extra-bundle": "~2.1.0" rather than ^2.0 if you are on 6.2/6.3 — the older tags' resolvers will trigger deprecation notices about ArgumentValueResolverInterface.

Laravel application (pattern harvesting)

  • Middleware for negotiation. Recreate the content-negotiation half with a single global middleware that parses Accept, picks a supported representation, and stores it on the request ($request->attributes->set('negotiated_format', ...)). Return 406 when nothing matches. This is ~60 lines and removes negotiation logic from every controller.
  • Attribute-driven argument resolution. If you want the request-binding half, add a route middleware or a base controller that reflects over $action method attributes and hydrates a DTO before the controller runs. This is the Laravel analogue of a Symfony value resolver and is the only piece of this bundle worth porting. Mirror the ValueResolverInterface contract from v2.1.0 while you're at it: a resolver that returns "nothing" to signal "not mine" is simpler to compose than a separate supports() method.
  • Keep DTOs and validation together. Map attributes → DTO, then validate with Validator::make($dto->toArray(), $rules) inside the same resolver. This preserves the "contract next to the handler" benefit without giving up Laravel's validation ecosystem.
  • Integration tip: if you run both Laravel and Symfony services, standardize the attribute names across both so a controller contract reads the same in each repo. That is the real leverage of a package like this — cross-framework consistency — and it does not require the bundle on the Laravel side.

Gotchas and Tips

  • Still effectively unmaintained — but now on the modern interface. v2.1.0 is a targeted compatibility fix (all value argument resolvers adapted to ValueResolverInterface), not a revival. There are still no dependents filing bugs, and no evidence of Symfony 7 readiness testing. Pin the version and keep an owner; the release makes it installable on 6.2+ without deprecation noise, not supported.
  • This release is a floor bump. ValueResolverInterface is 6.2+. If you were running the bundle on 5.4, upgrading will break at runtime; stay on the previous tag or upgrade Symfony. Check your composer.json constraint against your Symfony version before bumping.
  • Interface semantics changed under the resolvers. With ArgumentValueResolverInterface the container called supports() first; with ValueResolverInterface the resolver is invoked and signals "not mine" by returning an empty iterable. Consequences: (1) every resolver in the tag is now hit for every controller argument, so ordering and tag priority matter more; (2) a custom or overriding resolver that returns null/throws instead of [] will now break every action, not just its own. Return [] early and explicitly.
  • It will not install into a Laravel app as a "package." No auto-discovery, no service provider, no bindings. Any attempt results in unused classes at best. The honest framing is "reference implementation," not "dependency."
  • Attribute vs. annotation confusion. PHP 8 attributes fail quietly when the target is wrong or the class isn't imported — the resolver simply sees nothing. If an attribute "doesn't work," first verify it is a real #[Attribute] class with the correct TARGET_METHOD and that the use statement is present.
  • Content negotiation edge cases are the usual suspects: quality factors (q=), */* fallbacks, charset parameters, and vendor media types. Write a test for each before trusting the bundle's negotiation in production.
  • Debugging: in Symfony, inspect resolved request attributes via the profiler or a kernel.controller listener and dump() the argument map. If an attribute resolves to null/no argument, debug:container --tag=controller.argument_value_resolver lists what is actually registered and in what order — that is the fastest way to spot a resolver that never ran. On the Laravel side, log the DTO after hydration in your resolver — most bugs are "field name mismatch," not logic.
  • Extension points: the resolvers themselves (now ValueResolverInterface implementations) and the negotiator service definition are the intended seams. To customize, either register your own resolver with a higher tag priority or decorate the bundle's service — both are safer than subclassing internals. If you write custom resolvers, implement ValueResolverInterface (not the deprecated ArgumentValueResolverInterface) so they survive Symfony 7.
  • Exit strategy / equivalents. The functionality overlaps heavily with Symfony's native #[MapRequestPayload]/#[MapQueryString] and, historically, SensioFrameworkExtraBundle. For a Laravel team the true equivalents are FormRequest (binding + validation) and a negotiation middleware (content type). If you are adopting this bundle today, you are adopting a pattern, not a dependency — write the 100 lines yourself and keep the maintenance in-house.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle