Symfony HTTP Responder
ADR implemented in a nutshell. A viable alternative for AbstractController
, or most base
controllers really.
use ro0NL\HttpResponder\Bridge\Twig\Template;
use ro0NL\HttpResponder\Responder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class SomeHttpAction
{
public function __invoke(Request $request, Responder $responder): Response
{
return $responder->respond(new Template('home.html.twig'));
}
}
We call it Composition over Inheritance.
Installation
composer require ro0nl/http-responder
Enable the Symfony Bundle
return [
// ...
ro0NL\HttpResponder\Bundle\HttpResponderBundle::class => ['all' => true],
];
Using the framework, a default view listener invokes the responder out-of-the-box. You may update your controller actions as such:
use ro0NL\HttpResponder\Respond\Respond;
// ...
public function __invoke(Request $request): Respond
{
return new Template('home.html.twig');
}
Create a Providing Responder
Provide custom respond types using the ProvidingResponder
.
use ro0NL\HttpResponder\ProvidingResponder;
use ro0NL\HttpResponder\Respond\Respond;
use Symfony\Component\HttpFoundation\Response;
class MyRespond implements Respond
{
}
class MyProvidingResponder extends ProvidingResponder
{
protected function getProviders(): iterable
{
yield MyRespond::class => function (MyRespond $respond): Response {
return new Response('hello world');
};
}
}
Any type of ProvidingResponder
service is automatically tagged with http_responder
to be made available in the main
responder.
In case your responder implements the Responder
interface but serves as a provider it should be tagged manually.
Create a Decorating Responder
Add behaviors to the main responder using a decorator.
use ro0NL\HttpResponder\Responder;
use ro0NL\HttpResponder\Respond\Respond;
use Symfony\Component\HttpFoundation\Response;
class MyDecoratingResponder implements Responder
{
private $responder;
public function __construct(Responder $responder)
{
$this->responder = $responder;
}
public function respond(Respond $respond): Response
{
// provide a response and ignore/override default behaviors
if ($respond instanceof SpecialRespond) {
return new Response('special');
}
// provide the initial response with default behaviors
$response = $this->responder->respond($respond);
// apply some generic behavior
if ($respond instanceof MyRespond) {
// apply some specific behavior
}
return $response;
}
}
The bundle's main service identifier is http_responder
and is aliased to its corresponding interface.
Comparison Table
AbstractController |
Responder |
|
---|---|---|
get() |
|
|
has() |
|
|
generateUrl() |
||
forward() |
|
|
redirect() |
||
redirectToRoute() |
||
json() |
Serializer support) |
|
file() |
||
addFlash() |
||
isGranted() |
Security service) |
|
denyAccessUnlessGranted() |
Security firewall) |
|
renderView() |
Twig service) |
|
render() |
||
stream() |
||
createNotFoundException() |
throw ) |
|
createAccessDeniedException() |
throw ) |
|
createForm() |
Form service) |
|
createFormBuilder() |
Form service) |
|
getDoctrine() |
Doctrine service) |
|
getUser() |
Security service) |
|
isCsrfTokenValid() |
Csrf service) |
|
dispatchMessage() |
Messenger service) |
|
addLink() |
Contributing
See CONTRIBUTING.md