kamyshev/responder-bundle
A Symfony bundle that brings the responder pattern to your applications, converting handler results into HTTP responses and keeping controllers thin. It separates domain logic from response formatting for cleaner, more maintainable PHP code.
Read this first: kamyshev/responder-bundle is a Symfony bundle, not a Laravel package, and it is effectively unmaintained. Its only recent activity is v1.0.1, whose entire changelog is Replace kamyshev/array_find by kamyshev/array_actions — a transitive dependency rename, not a feature or fix. There is no service provider, no config file to publish, no facade, and no composer.json conflict entry that will protect you from installing it into a Laravel app. For a Laravel codebase the correct first step is still to not install it and read it as a pattern reference, because Laravel's router already implements ~90% of what this bundle does.
If you are inheriting a Symfony 3.x/4.0 app that already uses it, the minimal steps are:
composer require kamyshev/responder-bundle — pin ^1.0.1 if you want the current tree, or the exact old tag if your lockfile depends on kamyshev/array_find. Expect PHP 7.1-era constraints either way.app/AppKernel.php (Symfony 3) or config/bundles.php (Symfony 4).DependencyInjection/Configuration.php first — that file, not the README, is the source of truth for the responder registration format (a type → service-id map plus a fallback responder).Response. That listener uses the kamyshev/array_actions helper to resolve a value's type against your map — that lookup is where all your debugging will happen.First use case: a controller that returns a plain DTO or array instead of new JsonResponse(...), with a single registered responder that serializes anything of that type via the Symfony Serializer. The win is thin controllers and one place to change representation (HTML vs JSON) based on Accept.
The Laravel equivalent you should reach for instead: return an array/Arrayable (auto-JSON), an Illuminate\Http\Resources\Json\JsonResource, or any object implementing Illuminate\Contracts\Support\Responsable. That is the same architectural idea, maintained, and already wired into the framework.
$value; a response listener looks up a responder by the value's class and calls it to produce a Response. In Laravel this maps directly onto Responsable::toResponse($request) — the Router::prepareResponse path already checks for it. If you want the pattern without the dependency, implement Responsable on your DTOs.OrderConfirmation, Collection, array, never Response. In Laravel you can enforce this with a base controller respond() helper or a ResponseFactory macro, which is more honest and greppable than a magic listener.$request->getPreferredFormat(); the Laravel analogue is $request->expectsJson() in a middleware or a single Responder service injected into controllers.ResponderServiceProvider that binds OrderConfirmation::class to a closure, plus Responsable on the DTOs. Then delete the bundle.kamyshev/array_find → kamyshev/array_actions. The bundle is still Symfony-only, still 2018-era PHP constraints, still no Laravel integration.kamyshev/array_find (or another package requires it), composer update kamyshev/responder-bundle will pull array_actions alongside it and you can end up with both installed, or with a version-constraint conflict if array_actions requires a newer PHP. Diff composer.lock after the bump and check composer why kamyshev/array_actions before assuming nothing changed.kamyshev/array_actions. "My responder isn't being called" bugs frequently bottom out in the array-search helper rather than the bundle: first-match-wins ordering, loose vs strict comparison, and how the fallback is appended. Read that package's source, not the bundle README, when resolution misbehaves.instanceof with an ordered map; the first match wins, so registering a responder for a base class silently swallows all subclasses. Verify ordering in the config, not the docs.Handler + render() — keep both paths consistent or your API returns two different error shapes.kernel.response ordering relative to Twig/FOSRest/serializer bundles determines whether you get double-encoded JSON or a Response that nobody expected. Debug by logging the event priority, and never dump() and return from a controller that relies on the transform.mixed/scalars) is the only safe place to put "unknown type" logging. If you inherit this code, add one before you touch anything else.composer require here buys you an unmaintained Symfony listener you cannot register and should not want — v1.0.1 changes nothing about that.How can I help you explore Laravel packages today?