loading...

Hey Responder 👋, please respond to me with a Symfony response 📜

ro0nl profile image Roland Franssen ・2 min read

When working in a typical Symfony web application, we usually look at its controllers to spot any red flags the application might suffer from. Often a lot of magic happens here ...

A controller is a PHP function you create that reads information from the Request object and creates and returns a Response object. The response could be an HTML page, JSON, XML, a file download, a redirect, a 404 error or anything else. The controller executes whatever arbitrary logic your application needs to render the content of a page. (source)

In this post I like to focus on producing Symfony's HTTP response object, to be returned from the controller for rendering.

Symfony promotes inheriting from AbstractController as its best practice (source) ... wait what? Does that even scale?

I guess ¯_(ツ)_/¯, today you'll inherit 24 utility methods. Moreover, you rely on a service locator for this (not pure dependency injection). If this works for you, or you don't really care; keep on going!

But, if you're using the Action-Domain-Responder pattern (ADR) already, then I've got news for you ... meet the HTTP Responder: https://github.com/ro0NL/symfony-http-responder

Makes the "R" part a joy to deal with.
— me

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'));
    }
}

I've added a comparison-table to help you decide if you really need AbstractController 👍

The next step is to add a Kernel::VIEW event listener and respond from there, based on the controller result. In practice this means you are service dependency free by default!

return new Template('home.html.twig');
return new Redirect('/path');
return new RouteRedirect('route_name');

Or a more advanced example:

return (new Template('some.html.twig'))
    ->withStatus(500)
    ->withHeader('X-Hello', 'world')
    ->withFlash('success', 'Ah yeah')
    ->withLink('href', ['rel']);

Cheers,

Discussion

pic
Editor guide