Slim and Action-Domain-Responder

I’ve had a warm place in my heart for Slim for a long time, and especially so since recognizing the Action-Domain-Responder pattern. In this post, I’ll show how to refactor the Slim tutorial application to ADR.

One nice thing about Slim (and most other HTTP user interface frameworks) is that they are already “action” oriented. That is, their routers do not presume a controller class with many action methods. Instead, they presume an action closure or a single-action invokable class. So the Action part of Action-Domain-Responder already exists for Slim. All that is needed is to pull extraneous bits out of the Actions, to more clearly separate their behaviors from Domain and the Responder behaviors.

I.

Let’s begin by extracting the Domain logic. In the original tutorial, the Actions use two data-source mappers directly, and embed some business logic as well. We can create a Service Layer class called TicketService and move those operations from the Actions into the Domain. Doing so gives us this class:

<?php
class TicketService
{
    protected $ticket_mapper;
    protected $component_mapper;

    public function __construct(
        TicketMapper $ticket_mapper,
        ComponentMapper $component_mapper
    ) {
        $this->ticket_mapper = $ticket_mapper;
        $this->component_mapper = $component_mapper;
    }

    public function getTickets()
    {
        return $this->ticket_mapper->getTickets();
    }

    public function getComponents()
    {
        return $this->component_mapper->getComponents();
    }

    public function getTicketById($ticket_id)
    {
        $ticket_id = (int) $ticket_id;
        return $this->ticket_mapper->getTicketById($ticket_id);
    }

    public function createTicket($data)
    {
        $component_id = (int) $data['component'];
        $component = $this->component_mapper->getComponentById($component_id);

        $ticket_data = [];
        $ticket_data['title'] = filter_var(
            $data['title'],
            FILTER_SANITIZE_STRING
        );
        $ticket_data['description'] = filter_var(
            $data['description'],
            FILTER_SANITIZE_STRING
        );
        $ticket_data['component'] = $component->getName();

        $ticket = new TicketEntity($ticket_data);
        $this->ticket_mapper->save($ticket);
        return $ticket;
    }
}
?>

We create a container object for it in index.php like so:

<?php
$container['ticket_service'] = function ($c) {
    return new TicketService(
        new TicketMapper($c['db']),
        new ComponentMapper($c['db'])
    );
};
?>

And now the Actions can use the TicketService instead of performing domain logic directly:

<?php
$app->get('/tickets', function (Request $request, Response $response) {
    $this->logger->addInfo("Ticket list");
    $tickets = $this->ticket_service->getTickets();
    $response = $this->view->render(
        $response,
        "tickets.phtml",
        ["tickets" => $tickets, "router" => $this->router]
    );
    return $response;
});

$app->get('/ticket/new', function (Request $request, Response $response) {
    $components = $this->ticket_service->getComponents();
    $response = $this->view->render(
        $response,
        "ticketadd.phtml",
        ["components" => $components]
    );
    return $response;
});

$app->post('/ticket/new', function (Request $request, Response $response) {
    $data = $request->getParsedBody();
    $this->ticket_service->createTicket($data);
    $response = $response->withRedirect("/tickets");
    return $response;
});

$app->get('/ticket/{id}', function (Request $request, Response $response, $args) {
    $ticket = $this->ticket_service->getTicketById($args['id']);
    $response = $this->view->render(
        $response,
        "ticketdetail.phtml",
        ["ticket" => $ticket]
    );
    return $response;
})->setName('ticket-detail');
?>

One benefit here is that we can now test the domain activities separately from the actions. We can begin to do something more like integration testing, even unit testing, instead of end-to-end system testing.

II.

In the case of the tutorial application, the presentation work is so straightforward as to not require a separate Responder for each action. A relaxed variation of a Responder layer is perfectly suitable in this simple case, one where each Action uses a different method on a common Responder.

Extracting the presentation work to a separate Responder, so that response-building is completely removed from the Action, looks like this:

<?php

use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\PhpRenderer;

class TicketResponder
{
    protected $view;

    public function __construct(PhpRenderer $view)
    {
        $this->view = $view;
    }

    public function index(Response $response, array $data)
    {
        return $this->view->render(
            $response,
            "tickets.phtml",
            $data
        );
    }

    public function detail(Response $response, array $data)
    {
        return $this->view->render(
            $response,
            "ticketdetail.phtml",
            $data
        );
    }

    public function add(Response $response, array $data)
    {
        return $this->view->render(
            $response,
            "ticketadd.phtml",
            $data
        );
    }

    public function create(Response $response)
    {
        return $response->withRedirect("/tickets");
    }
}
?>

We can then add the TicketResponder object to the container in index.php:

<?php
$container['ticket_responder'] = function ($c) {
    return new TicketResponder($c['view']);
};
?>

And finally we can refer to the Responder, instead of just the template system, in the Actions:

<?php
$app->get('/tickets', function (Request $request, Response $response) {
    $this->logger->addInfo("Ticket list");
    $tickets = $this->ticket_service->getTickets();
    return $this->ticket_responder->index(
        $response,
        ["tickets" => $tickets, "router" => $this->router]
    );
});

$app->get('/ticket/new', function (Request $request, Response $response) {
    $components = $this->ticket_service->getComponents();
    return $this->ticket_responder->add(
        $response,
        ["components" => $components]
    );
});

$app->post('/ticket/new', function (Request $request, Response $response) {
    $data = $request->getParsedBody();
    $this->ticket_service->createTicket($data);
    return $this->ticket_responder->create($response);
});

$app->get('/ticket/{id}', function (Request $request, Response $response, $args) {
    $ticket = $this->ticket_service->getTicketById($args['id']);
    return $this->ticket_responder->detail(
        $response,
        ["ticket" => $ticket]
    );
})->setName('ticket-detail');
?>

Now we can test the response-building work separately from the domain work.

Some notes:

Putting all the response-building in a single class with multiple methods, especially for simple cases like this tutorial, is fine to start with. For ADR, is not strictly necessary to have one Responder for each Action. What is necessary is to extract the response-building concerns out of the Action.

But as the presentation logic complexity increases (content-type negotiation? status headers? etc.), and as dependencies become different for each kind of response being built, you will want to have a Responder for each Action.

Alternatively, you might stick with a single Responder, but reduce its interface to a single method. In that case, you may find that using a Domain Payload (instead of “naked” domain results) has some significant benefits.

III.

At this point, the Slim tutorial application has been converted to ADR. We have separated the domain logic to a TicketService, and the presentation logic to a TicketResponder. And it’s easy to see how each Action does pretty much the same thing:

  • Marshals input and passes it into the Domain
  • Gets back a result from the Domain and passes it to the Responder
  • Invokes the Responder so it can build and return the Response

Now, for a simple case like this, using ADR (or even webbishy MVC) might seem like overkill. But simple cases become complex quickly, and this simple case shows how the ADR separation-of-concerns can be applied as a Slim-based application increases in complexity.

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

Why MVC doesn’t fit the web

[MVC is] a particular way to break up the responsibilities of parts of a graphical user interface application. One of the prototypical examples is a CAD application: models are the objects being drawn, in the abstract: models of mechanical parts, architectural elevations, whatever the subject of the particular application and use is. The “Views” are windows, rendering a particular view of that object. There might be several views of a three-dimensional part from different angles while the user is working. What’s left is the controller, which is a central place to collect actions the user is performing: key input, the mouse clicks, commands entered.

The responsibility goes something like “controller updates model, model signals that it’s been updated, view re-renders”.

This leaves the model relatively unencumbered by the design of whatever system it’s being displayed on, and lets the part of the software revolving around the concepts the model involves stay relatively pure in that domain. Measurements of parts in millimeters, not pixels; cylinders and cogs, rather than lines and z-buffers for display.

The View stays unidirectional: it gets the signal to update, it reads the state from the model and displays the updated view.

The controller even is pretty disciplined and takes input and makes it into definite commands and updates to the models.

Now if you’re wondering how this fits into a web server, you’re probably wondering the same thing I wondered for a long time. The pattern doesn’t fit.

Read the rest at Why MVC doesn’t fit the web.

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

The “Micro” Framework As “User Interface” Framework

(The following is more exploratory than prescriptive. My thoughts on this topic are incomplete and in-progress. Please try to treat it accordingly.)


tl;dr: “Micro” frameworks are better described as “user interface” frameworks; perhaps there should be corollary “infrastructure” frameworks; consider using two frameworks and/or two containers, one for the user interface and a separate one for the core application.

I.

When we talk about “full stack” frameworks, we mean something that incorporates tools for every part of a server-side application:

  • incoming-request handling through a front controller or router
  • dispatching routes to a page controller or action (typically a class constructed through a DI container)
  • database, email, logging, queuing, sessions, HTTP client, etc.; these are used in a service, model, controller, or action to support business logic
  • outgoing-response creation and sending, often combined with a template system

Examples in PHP include Cake, CodeIgniter, Fuel, Kohana, Laravel, Opulence, Symfony, Yii, Zend Framework, and too many others to count.

When we talk about “micro” frameworks, we mean something that concentrates primarily on the request-handling and response-building parts of a server-side application, and leaves everything else out:

  • incoming-request handling through a front controller or router
  • dispatching routes to a page controller or action (typically a closure that receives a service locator, though sometimes a class constructed through a DI container)
  • outgoing-response creation and sending, often combined with a template system

Slim is the canonical PHP example here; others include Equip, Lumen, Silex, Radar, Zend Expressive, and (again) too many others to count.

II.

I have asserted elsewhere that, in an over-the-network HTTP-oriented server-side application, the View (of Model-View-Controller) is not the template. The View is the entire HTTP response: not just the HTML or the body, but the status line, the headers, all cookies, and so on. That is, the full HTTP response is the presentation; it is the output of the server-side application.

If the HTTP response is the output, then what is the user input into the server-side application? It is not the form being submitted by the user, per se. It is not a key-press or button-click or mouse-movement. The input is the entire HTTP request, as sent by the client to the server.

That means the user interface for a server-side application is not “the HTML being viewed on the screen.” The user interface is the HTTP request and response.

Now, for the big jump:

If the user interface is the request (as input), and the response (as output), that means micro-frameworks are not so much “micro” frameworks, as they are “user interface” frameworks.

Consider that for a moment before continuing.

III.

If it is true that “micro” frameworks are more accurately described as “user interface” frameworks, it opens some interesting avenues of thought.

For one: it means that full-stack frameworks combine user interface concerns with other concerns (notably but not exclusively infrastructure concerns).

For another: perhaps in addition to user interface (“micro”) frameworks, it would be useful to have something like a separate “infrastructure” framework. It might not even be a framework proper; it might only be a container for shared services that have no relation to any user interface concerns. (I can imagine extracting such a toolkit collection from any of the full-stack frameworks, to be offered on its own.)

IV.

Speaking of containers:

It is often the case, even with user interface (“micro”) frameworks, that developers will store their infrastructure and services objects in the framework-provided container. Or, that they will build “providers” or “configuration” for the framework-provided container, so that the container can create and retain the infrastructure and services objects.

But if it is true that the “micro” framework is a “user interface” system, why would we manage infrastructure and domain objects through a user interface container? (This a variation on “Why is your application/domain/business logic in your user interface controller?”)

Perhaps it would be better for the infrastructure and/or domain objects to be managed through a container of their own. Then that completely separate container can be injected into any user interface container. The benefit here is that the infrastructure and/or domain objects are now fully separated from the user interface layer, and can be used with any user interface framework, even one that uses a completely different container for its own user interface purposes. (This is a variation on “composition to reduce coupling.”)

V.

To conclude:

It might be worth considering the use of two frameworks in server-side applications, each with its own container: one for the user interface concerns, and a separate one for infrastructure/domain concerns. (The latter might be composed into any user interface framework, whether one for the web or one for the command line.)

And, given that lots of application work starts mostly as infrastructure coordination, with little domain logic, having a second framework separated from the user interface makes it easier to put a boundary around the infrastructure-based application code, separating it from the user interface code. The work on each can proceed in parallel; the user interface coders can mock the results from the application layer, and build everything out on their own path, while the application coders don’t need to worry too much about presentation concerns (whether HTTP or CLI based).


Unlike some other people, I am not my code, or my books, or my blog posts. Given the tentative nature of the above essay, review and criticism (especially substantial criticism) are vital. It won’t hurt me in the least bit; indeed, I encourage it.

Thanks for reading.

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

Domain Logic and Email Templates

From an email conversation with a reader:

Hi Paul,

I’ve been following your writing and examples about the ADR pattern for some time now. It’s taken me awhile to wrap my head around it but ADR has really added a lot of structure to my code and I’m thankful for your work!

One dilemma that I’ve been struggling with is how to organize emails that are sent out by my service classes. Currently my business logic dictates when to send an email and most of them contain html and text templates. It just feels wrong to include those email templates within the Domain. Do you have any recommendations? Any help you can provide would be greatly appreciated.

In a somewhat related question – Recently I’ve been organizing my “views” folders within the folders of their parents (Http, Mail). I think I based it on your ADR example on github. Do you still prefer this method or do you lean towards organizing within a “resources” folder?

My intuition is that you are right to keep the email templates out of the domain.

In a way, sending an email as part of a web request/response cycle is like sending two responses: the normal HTTP response, and the email response. With that in mind, it might make sense to think of the HTML + Text email templates as part of a presentation layer. Or, as a combination of infrastructure (the email-sending client) plus presentation (the templates). That would be how to think about the separation of concerns there.

Here’s an example of what that separation of concerns might look like in a package directory structure:

resources/
    templates/
        web/
            # web page templates
        email/
            message-1/
                message-1.html
                message-1.txt
            message-2/
                message-2.html
                message-2.txt
src/
    Domain/
        AppService/
            FooAppService.php
            BarAppService.php
        EmailInterface.php
        # ... other domain classes
    Infrastructure/
        DataSource/
            # ... mappers, tables, etc
        Emailer.php # implements Domain\EmailInterface
    Web/
        Foo/
            FooAction.php
            FooResponder.php
        Bar/
            BarAction.php
            BarResponder.php

The specifics of directory structure are not important, as long as you see that the Emailer class is separated from the Domain application services (or use cases, or whatever).

The Emailer class, for its part, might be a facade [1] that coordinates between a “real” emailer (e.g. Swiftmailer or PhpMailer) and a template class, to put together and then send the email. You could configure the Emailer class with the template location (resources/templates/email/*) and inject it into your application service (which depends on the EmailInterface).

Now, sending emails inline as part of the web request might be fine in a lower-traffic situation. But as volume scales up, this kind of separation will make it easy to extract all email-sending to a workers. Then the Emailer can queue emails to the workers instead of sending them inline with the web request; the email-sending can become the job of a queue worker, and the template work will go there instead.

As far as where to put templates for views:

The extended example ADR code on GitHub is a few years old at this point. I still think it’s a reasonable setup, especially for people transitioning out of pseudo-MVC toward ADR, but it might do well to receive an update (or some examples of variations).

I don’t prefer any particular method or structure on where to put templates. Sometimes it makes sense to keep templates near the things using them, sometimes it makes sense to collect them all one place. The needs of the system, and the prior experiences of the developer(s), will be the deciding factor as far as I’m concerned. I had PHP-PDS on the brain when I replied, so the pds/skeleton with its “resources” directory was at hand.


[1] A real facade, not a Laravel one. 😉

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

Controllers and Domain Exceptions

A few months ago I had a great email conversation with a correspondent about how to handle business logic exceptions in his controller code. His message follows, lightly edited for brevity and clarity:

I think controller has single responsibility – to mediate communication between caller’s context and actual business logic services. (I believe business logic services should be unaware of caller’s context, be it HTTP request or CLI.)

Given that services should be unaware of who called them, they should not throw HTTP-specific exceptions. So instead of throwing a Symfony HttpNotFound Exception, the service would throw ObjectNotFound (which is HTTP agnostic) in cases where DB record could not be found.

Yet at the same time the logic that converts exceptions to HTTP responses expects HTTP-specific Symfony exceptions. This means that the exception thrown by service needs to be transformed into Symfony exception.

One of solutions I see to this is that the controller could take that responsibility. It would catch domain exceptions thrown by service and wrap them into appropriate HTTP exceptions.

class FooController
{
    public function fooAction()
    {
        try {
            $this->service->doSomething('foo');
        } catch (ObjectNotFound $e) {
            throw new NotFoundHttpException('Not Found', $e);
        } catch (InvalidDataException $e) {
            throw new BadRequestHttpException('Invalid value', $e);
        } // ...
    }
}

The downside I see with this approach is that if I have many controllers I will have code duplication. This also could lead to big amount of catch blocks, because of many possible exceptions that could be thrown.

Another approach would be to not have try/catch blocks in controller and let the exceptions thrown by service bubble up the stack, leaving the exception handling to exception handler. This approach would solve the code duplication issue and many try/catch block issue. However, because the response builder only accepts Symfony exceptions, they would need to be mapped somewhere.

It also feels to me that this way the controller is made cleaner, but part of controllers responsibility is delegated to something else, thus breaking encapsulation. I feel like it’s controllers job to decide what status code should be retuned in each case, yet at the same time, cases usually are the same.

I truly hope you will be able to share your thoughts on this and the ways you would tackle this.

If you find yourself in this situation, the first question to ask yourself is, “Why am I handling domain exceptions in my user interface code?” (Remember: Model-View-Controller and Action-Domain-Responder are user interface patterns; in this case, the user interface is composed of an HTTP request and response.) Domain exceptions should be handled by the domain logic in a domain-appropriate fashion.

My correspondent’s first intuition (using domain-level exceptions, not HTTP-specific ones) has the right spirit. However, instead of having the domain service throw exceptions for the user interface controller to catch and handle, I suggest that the service return a Domain Payload with domain-specific status reporting. Then the user interface can inspect the Domain Payload to determine how to respond. I expand on that approach in this post.

By way of example, instead of this in your controller …

class FooController
{
    public function fooAction()
    {
        try {
            $this->service->doSomething('foo');
        } catch (ObjectNotFound $e) {
            throw new NotFoundHttpException('Not Found', $e);
        } catch (InvalidDataException $e) {
            throw new BadRequestHttpException('Invalid value', $e);
        } // ...
    }
}

… try something more like this:

class FooController
{
    public function fooAction()
    {
        $payload = $this->service->doSomething('foo');
        switch ($payload->getStatus()) {
            case $payload::OBJECT_NOT_FOUND:
                throw new NotFoundHttpException($payload->getMessage());
            case $payload::INVALID_DATA:
                throw new BadRequestHttpException($payload->getMessage());
            // ...
        }
    }
}

(I am not a fan of using exceptions to manage flow control; I’d rather return a new Response object. However, I am trying to stick as closely to the original example as possible so that the differences are more easily examined.)

The idea here is to keep domain logic in the domain layer (in this case, a service). The service should validate the input, and if it fails, return a “not-valid” payload. The service should catch all exceptions, and return a payload that describes the kind of error that occurred. You can then refine your controller to examine the Domain Payload and handle it however you want.

Using a Domain Payload in this way is not a huge leap. Essentially you move from a try/catch block and exception classes, to a switch/case block and status constants. What’s important is that you are now handling domain-level exceptions in the domain and not in the user interface layer. You are also encapsulating the status information reported by the domain, so that you can pass the Domain Payload object around for something other than the controller to inspect and handle.

Encapsulation via Domain Payload opens the path to a more significant refactoring that will help reduce repetition of response-building logic across many controller actions. That next refactoring is to separate out the response-building work to a Responder, and use the Responder in the controller action to return a response. You can then pass the Domain Payload to the Responder for it to handle.

class FooController
{
    public function fooAction()
    {
        $payload = $this->service->doSomething('foo');
        return $this->responder->respond($payload);
    }
}

class FooResponder
{
    public function respond($payload)
    {
        switch ($payload->getStatus()) {
            case $payload::OBJECT_NOT_FOUND:
                throw new NotFoundHttpException('Not Found', $e);
            case $payload::INVALID_DATA:
                throw new BadRequestHttpException('Invalid value', $e);
            // ...
        }
    }
}

Once you do that, you’ll realize the majority of your response-building logic can go into a common or base Responder. Custom cases can then be be handled by controller- or format-specific Responders.

And then you’ll realize all your Action logic is all pretty much the same: collect input from the Request, pass that input to a Domain-layer service to get back a Domain Payload result, and pass that result to a Responder to get back a Response. At that point you’ll be able to get rid of controllers entirely, in favor of a single standardized action handler.

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

“Action Injection” As A Code Smell

Circumstance has conspired to put Action Injection discussions in front of me multiple times in the past few days. Having seen the approach several times before, I have come to think that if Action Injection is the answer, you might be asking the wrong question. I find it to be a code smell, one that indicates the system needs refactoring or reorganizing.

Action Injection …

As far as I can tell, the term “Action Injection” originates with Alex Meyer-Gleaves in a 2010 article on ASP.NET MVC development. He summarizes Action Injection in this way:

Your [controller class] constructor is provided the dependencies [by the DI container] that are shared by all actions in your controller, and each individual action [method] can request any additional dependencies that it needs.

To expand on that, let’s say you have a controller class with several action methods in it. You realize after a while that the different action methods have slightly different dependencies. For example, some of the methods need a logger, while others need a template system, or access to the router. But you don’t want to pollute the controller class constructor with these method-specific dependencies, since those dependencies will be used only if that particular action method gets invoked.

With Action Injection, when you pull the controller from your dependency injection container and call a particular action method, the DI container will automatically pass the right dependencies for the method call arguments. Voila: now you can define all the common dependencies as parameters on the controller constructor, and all the action-specific dependencies as parameters on the method definition.

You can see a PHP-specific description of the problem, with Action Injection as the solution, in this Symfony pull request:

https://github.com/symfony/symfony/pull/21771

You can also hear about it in this presentation from Beau Simensen, from around 32:21 to 34:31:

https://www.youtube.com/watch?v=JyrgwMagwEM&feature=youtu.be&t=1941

The Yii and Laravel containers appear to support this behavior as well, using the term “method injection.” (I think that’s a misnomer; the term appears overloaded at best, as sometimes it may mean “methods called by the DI container at object-creation time” instead of “resolving method arguments at call-time”.) Perhaps other DI containers support Action Injection as well.

… As A Code Smell

The explicit reason for using Action Injection is “to reduce dependencies or overhead” when constructing an object. You don’t want to have to pass in a dozen dependencies, when only three are used in every method, and the others are used only in specific methods.

But the fact that your controller has so many dependencies, used only in some cases and not in others, should be an indicator that the class is doing too much. Indeed, it’s doing so much that you cannot call its action methods directly; you have to use the dependency injection container not only to build the controller object but also to invoke its action methods.

Reorganizing To Avoid Action Injection

What approaches exist to help you avoid the Action Injection code smell? I assert that the better solution is to change how you organize your controller structures.

Instead of thinking in terms of “a controller class with action methods,” think in terms of “a controller namespace with action classes.” Actions are the targets for your routes anyway, not controller classes per se, so it makes sense to upgrade actions to “first-class” elements of the system. (Think of them as single-action controllers, if you like.)

Thus, instead of …

<?php
namespace App;

class BlogController {
    public function browse() { ... }
    public function read() { ... }
    public function edit() { ... }
    public function add() { ... }
    public function delete() { ... }
}

… reorganize to:

<?php
namespace App\BlogController;

class Browse { ... }
class Read { ... }
class Edit { ... }
class Add { ... }
class Delete { ... }

Then the DI container can use plain old constructor injection to create the Action object, with all of its particular dependencies. To invoke the Action, call a well-known method with the user input from the route or request. (I like __invoke() but others may prefer exec() or something similar.)

In fact, I realized only after watching the Simensen clip a second time that his example is a single-action controller in everything but name. His example code was this …

<?php
class Home {
    /**
     * @Route("/myaction", name="my_action")
     */
    public function myAction(
        Request $request,
        Router $router,
        Twig $twig
    ) {
        if (!$request->isMethod('GET')) {
            return new RedirectResponse(
                $router->generateUrl('my_action'),
                301
            );
        }

        return new Response(
            $twig->render('mytemplate.html.twig')
        );
    }
}

… but the controller action method parameters might just as well be Action class constructor parameters:

<?php
namespace Home;

class MyAction {

    public function __construct(
        Request $request,
        Router $router,
        Twig $twig
    ) {
        $this->request = $request;
        $this->router = $router;
        $this->twig = $twig;
    }

    /**
     * @Route("/myaction", name="my_action")
     */
    public function __invoke() {
        if (!$this->request->isMethod('GET')) {
            return new RedirectResponse(
                $this->router->generateUrl('my_action'),
                301
            );
        }

        return new Response(
            $this->twig->render('mytemplate.html.twig')
        );
    }
}

(UPDATE: That example code looks like it originates from Kevin Dunglas and his DunglasActionBundle — which is itself a single-action controller implementation for Symfony.)

Action Domain Responder

For more on this organizational structure, please read my Action Domain Responder offering. ADR is a refinement of MVC that is tuned specifically to server-side request/response over-the-network interactions.

But you need not go full ADR to avoid Action Injection. Just using single-action controllers will do the trick. Then you can have well-factored single-responsibility controller classes that do not require a DI container in order to call their action methods, and Action Injection becomes a thing of the past.

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

Toward A Better Separation of Session Behaviors in PHP

Andrew Shell asks, What is the best way to handle sessions with ADR? (The problem is that the built-in PHP session extension combines the concerns of reading input, managing storage, and sending output; the solution is a domain-layer session-data manager.)

I’ve reached a point with a couple of my Radar projects where I need to add a login and set permissions. I’m trying to figure out the best way to handle this, especially with PSR-7 and ADR. …

[In Action-Domain-Responder] it’s ok to read the session cookie in an Input class, and it’s ok to write the cookie in a Responder class, but pretty much everything else should be in the Domain layer. …

[In the Domain layer,] Cadre.DomainSession takes a session id (or generates one) and loads session data from storage. It’s smart enough to handle regenerating session ids and cleaning up expired sessions.

Read the whole article at FutureProof PHP for examples and links!

UPDATE: Reddit discussion.

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

“A False Sense of Simplicity”

These year-old posts from Piotr Solnica are about Ruby On Rails …

… but the experiences related therein should be valuable to anyone using or building a full-stack PHP framework. (I can imagine it applying to CMSes as well.)

Does this story from Piotr remind you of any framework-based project you’ve worked on in PHP?

Once, I joined an existing project. It was a huuuuge app which was running an on-line shopping community website. Complicated sales model, complicated promotions, complicated product setups, coupons, user groups, messages – it had it all. I joined them to help ship a few new features. One of my early tasks was to … add a link to something on some page. It took me few days to add this stupid link. Why? The app was a big ball of complex domain logic scattered across multiple layers with view templates so complicated, it wasn’t even simple to find the right template where the link was supposed to be added. Since I needed some data in order to create that link, it wasn’t obvious how I should get it. There was a lack of internal application APIs and relying on ActiveRecord exclusively made it extremely difficult.

I’ve consulted on projects like that more than once. Indeed, the posts might well have been subtitled “The Perils of Convenience-Oriented Development”:

People are attracted by Rails because it gives you a false sense of simplicity, whereas what really happens is that complexity is being hidden by convenient interfaces.

Read both of the posts, and see if you can relate. They just reinforce to me that this is what to expect when you embed your domain logic in your user interface logic.

Remember: with server-side web-based applications, the user interface is the HTTP request and response. Any code that reads from the request, or that writes to the response, is part of the user interface. Putting your domain logic in the user interface is convenient to start with, but as soon as things become even a little bit complex, that “convenience” becomes a burden.

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

Atlas ORM 1.2.0 Released

The 1.2.0 release adds the ability to define WHERE conditions on relationships. (The 1.1.0 release added functionality to ignore foreign key string case when wiring up objects in memory, and 1.0.0 was released pretty quietly a couple of weeks ago.)

Try it out today, because you like keeping your persistence layer separate from your domain layer.

Now, read on for some history, if you care about that kind of thing.


Many years ago, we on the Solar project developed Solar_Sql_Model, an Active Record type of ORM. Overall I liked it well enough, though (as with anything) it had its strengths and weaknesses.

Since then, after extracting the Solar components to Aura libraries, I’ve mostly lived without ORMs. The majority of my legacy consulting work has not made use of them; where a legacy project did have an ORM of some sort, it was a custom in-house piece of work.

However, about three years ago, I hired on with a startup to build out their backend from scratch. At the time, I wanted to do “real” Domain-Driven Design, with entities and aggregates and value objects and everything else. That meant keeping the domain system separate from the persistence system, and that in turn meant Active Record was not an option. Doctrine, a domain model data mapper, was the next logical choice, but on review it was not to my liking. (The annotations, among other things about Doctrine, just rubbed me the wrong way.)

So instead of an Active Record implementation, or Doctrine, I figured that it would be enough to use a Table Data Gateway on top of Aura.Sql and Aura.SqlQuery to retrieve rows, then map the rows over to domain objects. This was fine, for as far as it went, but the problem was “relationships.” Oh dear Codd, the relationships.

Selecting one or many objects from a single table was no big deal, but doing multiple selections from multiple tables and building up the selection statements for those relationships was a tedious, tiresome, and time-consuming burden. (Wiring them up in memory once they’d been selected was not too bad, given Aura.Marshal, but it was still more effort than I’d’ve rather been expending.)

So it all “worked,” but it was just not satisfying at all. The DDD portions, for their part, worked out great, as did the separation of the domain layer from the persistence layer, so I was pretty sure I was on something like the right track.

Then I read this article from Mehdi Khalili. It’s fantastic and you should read the whole thing. In summary, Khalili points out that it is perfectly reasonable to use a persistence model in addition to a domain model. That is, you do not necessarily have to map directly from the database to domain objects; you can map from the database to persistence objects for the data, and then later compose or map the persistence model into the domain model for behaviors.

This was a revelation to me, something that I’d never considered, or even heard of before. It alleviates wide swaths of DDD-related burdens.

As a result of my relationship-related burdens at the startup, and after reading the Khalili article, I put together Atlas, a mapper for your persistence model. Like everything else I’ve been doing for the past several years, Atlas is built in discrete layers:

  • PDO at the very bottom;
  • Aura.Sql around that, to provide convenience methods for binding and fetching;
  • Aura.SqlQuery in parallel, to support query building;
  • all of those composed into a table data gateway system to emit Row objects from tables;
  • and finally a mapper system on top of that to emit Record objects composed of table Rows and their relationships

As such, each Record object is composed of a Row (from the “main” table) and its Related objects (themselves Records, each of which is composed of a Row and Relateds, and so on).

Atlas uses the term “Record” to indicate that the object is not a domain entity or aggregate. You can use Records directly for straightforward CRUD/BREAD operations, or you can map them over to your domain objects.

Fetching deep relationship structures is no big deal; see this article from Andrew Shell using 25 tables in different complex relationships. (Andrew’s project also shows how to keep the persistence and domain layers separate, and incorporates a debug bar implementation for Atlas.)

So, if you want a data mapper implementation that models your persistence layer, and the relationships therein, Atlas is just the thing for you. Try it out today!

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

Symfony 4: Directory Structure, and Common Practices

Fabien has published his plans for the new Symfony 4 directory structure. Not that it matters much to anyone in Symfony-land, where I have no status that I’m aware of, but I am happy to see the changes described.

Having said that, and recognizing that Fabien obviously has final say over his own projects …

The new etc/ directory is the equivalent of the current app/config/ directory.

Web files under web/

… it might be nice if Symfony 4 adopted more existing common practices, used by roughly 70% of Packagist packages. That is, to use config/ for the top-level config directory, and public/ for the top-level document-root directory.

More specifically:

  • config/ is used ~10x more than etc/ (ref)

  • public/ is used ~2x more than web/ (ref)

As a side note, that research resulted in the pds/skeleton publication.

(This blog post originated as a comment on Reddit.)

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn