On Project Structure; or, The Framework/App Is Not Special

(I apologize for the hasty writing here; this subject makes me impatient.)

Reading this post from Code Rabbi makes me reflect on project structure and organization. Frankly, most project structures (as from CodeIgniter, Cake, and all the popular frameworks since then) strike me as misdirected. They’re examples of why the project maintainers think their code is somehow special and different, and that the application built from it is also somehow special and different.

Your framework and application code are not special. Their code does not go in a special place. There’s no need for a top-level “app” directory with its own special subdirectories. There’s no need for a special naming convention to keep your different application-specfic code in specific places.

We had PSR-0, and now have PSR-4, and the Composer autoloader, to handle all that for you. Just use namespaces. All you need for code at the top level of your project is a “src” directory, where all your app code goes, just like all your library code goes in a “src” directory in a library package.

Instead of /app/controllers and /app/models, you have /src/Controller and /src/Model, or however else you want to organize your namespaced code. Then there’s no need for a special autoloading system or for hard-coded paths just for your application-level code. Add one single line to Composer that points to the src directory and voila, everything inside it loads for you.

That’s it. Nothing special. Just like every other library in your system.

(Again, this was hastily written. Please ask for clarficiation if you feel you need it.)

DRY is about Knowledge

From Matthias Verraes:

“Don’t Repeat Yourself” was never about code. It’s about knowledge. It’s about cohesion. If two pieces of code represent the exact same knowledge, they will always change together. Having to change them both is risky: you might forget one of them. On the other hand, if two identical pieces of code represent different knowledge, they will change independently. De-duplicating them introduces risk, because changing the knowledge for one object, might accidentally change it for the other object.

This is a great observation, one I had not considered before. It makes me feel a lot better about the very few and very minor duplications of code in the various independent and decoupled libraries in Aura. In short, DRY is not a reason to couple code libraries with similar behaviors; instead, it is a reason to have a single canonical source of knowledge within a system.

Back On The Market!

After a year spent writing my book, working on Aura, speaking at conferences and user groups, advising startups, and proposing new design patterns, I am back on the market.

I’ve been writing PHP code since 1999, and in that time I’ve been everything from a junior developer to a VP of Engineering. If you have a PHP codebase that requires some attention, especially a legacy app that needs to be modernized, I’m your man. I’m also excellent as a leader, mentor, manager, and architect, on small teams and on large ones.

Resume and references available on request. Contact me by email (pmjones88 at gmail) or on Twitter @pmjones if you want to talk!>

UPDATE (Tue 19 Aug): Well that was quick. I’m off the market again, and looking forward to productive efforts with my new employer. My deepest gratitude to everyone who expressed interest; I am truly humbled by the whole experience. Thank you to all.

Soccer, Development, and The Value Of Teamwork

The lesson of soccer is that individual effort will often suffice when things are relatively easy. But in order to surmount the more difficult challenges, you will almost always need reliable teammates of one sort or another.

I assert the same is true in development efforts. A single developer working alone can do good work, but a team of frontend devs, backend devs, devops, and DBAs can do stuff that is truly amazing. Combine your comparative advantages instead of trying to do everything yourself. Via Vox Popoli: Calcio is life.

Action-Domain-Responder, Content Negotiation, and Routers

While talking about Action-Domain-Responder on the Crafting Code Tour, one of the common questions I got was: “Where does content negotiation happen?” My response was always: “Where does it happen in Model-View-Controller?” That opened up a discussion on how content negotiation is a tricky bit that can go in different places, depending on how you want the concerns separated, and is not a problem specific to ADR.

However, I’ve not really been satisfied with that outcome. I enjoyed the question and the discussion, but it never seemed to resolve itself. We were left with this tension between resource conservation and proper separation of concerns. Should negotiation happen in the the Action (Controller), the Domain (Model), or the Responder (View)?

At first it seems like this is clearly a (re)presentation issue, and as such ought to go in the Responder or View. But if the Responder cannot present an acceptable content type for the request, that means we have done a lot of work in the Domain to build objects that will be discarded in favor of a “406 Not Acceptable” response. This is not a good use of our limited resources.

Perhaps the Domain is the place for negotiation? I think we can dismiss this outright. The Domain should not be in charge of returning different presentations of its data.

Finally, we might try negotiation in the Action (Controller). Here we examine the request, and query the Responder to see what content types it can present in responses. (Alternatively, we embed the available content types in both the Action and Responder, duplicating that information somewhat.) If the negotiation fails in the Action, we skip the Domain work and instruct the Responder to return a “406 Not Acceptable”. But that means the Action is now responsible for at least a little bit of the response-building logic. It’s not horrible, but it does not seem as clean as it could be.

After thinking about this for a while, I am beginning to think it is reasonable to perform what I will call a “first filter” on the Accept header at the Front Controller level, specifically in the Router. We already consider the Router as a guard to map incoming requests to appropriate Actions, inspecting the path, HTTP method, and other request information. Inspecting the acceptable types seems a reasonable addition to these elements.

A full content negotiation at the Router level is probably overkill. Really, all the Router needs to know is what content types are provided through particular Route (whether an MVC or ADR one). The matching logic can do a naive check of the Accept request header to see if one of the provided types is present with a non-zero “q” value. If none of the types is present, the Router can move along to the next route, possibly tracking the failure so a Dispatcher can directly invoke a Responder for routing failures. This way, the Router never invokes a non-matching Action, thereby conserving the Domain resources. If the match is successful, the Responder can do the “real” content negotiation work, using an Accept header value passed to it as input from the Action along with the Domain data.

As a proof of concept, I have modified the Aura.Router library to recognize “accept” specifications on the route, and the tests indicate it seems to work just fine.

An Updated Preview Of Aura.Auth

It can be difficult to find a truly standalone, authentication-only library, and Aura.Auth fits that bill.

The library is still under development, but the major pieces are all now in place:

Each layer can handle custom implementations. There are instructions for custom adapters, custom session managers (including session-less authentication), and custom services.

Via An Updated Preview Of Aura.Auth.

Modernizing Legacy PHP: From Service Locator To Dependency Injection

In an earlier article I described how to start moving away from singletons in favor of dependency injection. It occurs to me that the process for moving away from Service Locator is almost exactly the same, except that we use the container outside the class instead of inside it.

Let’s say we have a class that uses a Service Locator. First we examine the class for all uses of the locator. Then, we create constructor parameters for the dependencies it extracts from the locator, and add setter code for those dependencies in the constructor body. For example, we can convert the above Service Locator example classes to these dependency-injected variations:

<?php
class FooClass
{
    protected $db;
    public function __construct(Database $db)
    {
        $this->db = $db;
    }
}

class BarClass
{
    protected $db;
    public function __construct(Database $db)
    {
        $this->db = $db;
    }
}
?>

Finally, any time we instantiate one of these dependency-injected classes, we use the locator outside the class to retrieve the dependencies. We then pass them to the new call for the class. For example:

<?php
// for FooClass
$db = $container->get('db');
$foo = new FooClass($db);

// for BarClass
$db = StaticContainer::get('db');
$bar = new BarClass($db);
?>

Now the class dependencies are explicit and predictable, instead of implicit and unpredictable (i.e., the class might depend on any combination of dependencies hidden inside the container). It is also somewhat easier to build a test, since we only have to build the dependencies themselves, not the container that holds the dependencies.

Afterword

Are you overwhelmed by a legacy PHP application? Have you inherited a spaghetti mess of code? Does it use globals everywhere, so that a fix in one place causes a bug somewhere else? Does every feature addition feel like slogging through a swamp of includes?

It doesn’t have to be that way. “Modernizing Legacy Applications in PHP” gives you step-by-step instructions on how to get your legacy code under control by eliminating globals and separating concerns. Each chapter shows you exactly one task and how to accomplish it, along with common questions related to that task.

When you are done, you will come and go through your code like the wind. Your application will have become autoloaded, dependency injected, unit tested, layer separated, and front controlled. And you will have kept it running the whole time.

Buy the book today!

Aura.SqlQuery 2.0.0 Stable Release

Aura.SqlQuery provides provides a truly independent, fully decoupled package of query-building tools for PHP 5.3 and up. With it, you can use object-oriented techniques to create SELECT, INSERT, UPDATE, and DELETE queries. The package comes with a set of common base query objects, and provides specialized objects for MySQL, PostgreSQL, SQLite, and Microsoft SQL Server.

When we say “truly independent and fully decoupled” we really mean it. The SqlQuery package has no dependencies on any particular database connection system or abstraction layer. For example, you can build a SELECT query, then pass the finished query string to a PDO connection, a mysql connection, or through the database abstraction layer of your choice. This means the package is suitable for any framework or application that needs a query-building mechanism.

Via Aura.SqlQuery v2 Stable Release.

Refactoring To Action-Domain-Responder

The v1 version of the Aura framework includes a controller to handle web assets. The idea for this controller was that an Aura package might have images, scripts, and stylesheets that need to be publicly available, but in development you don’t necessarily want to copy them to a public document root every time you change them. The framework dispatches all “/asset/*” routes to the asset controller, which in turn reads the requested package asset from the file system and places its contents into the response body. Performance-wise this is horrible, so in a production environment one would use a build process to copy all the package assets to a static asset server, but in a local development environment it is a valuable convenience.

Take a look at the v1 version of the asset controller. It is constructed as a Page Controller within an MVC architecture. The default actionIndex() method receives an Aura package name in the form of Vendor.Package and a trailing file path indicating the asset to load from that package, then reads that file from the package and loads it into the response body.

That v1 version is a mess. The Controller handles the response-building entirely, and there is no Model separation at all. Let’s try refactoring it to an Action-Domain-Responder architecture and clean it up some for a v2 version. (For this example refactoring, we have Hari KT to thank for getting us started.)

  1. First, we need to extract the Domain portions of the code. After some discussion, we determined that the Domain here is the file-reading portions of the code. Instead of an Aura-specific Vendor.Package algorithm, we build a map of vendor/package keys that point to arbitrary directory prefixes (typically but not necessarily in a Composer installation). Finally, we figure that the caching elements would be better as part of a build process rather than on-the-fly, so we remove those caching elements; this reduces a significant portion of the Domain work.

  2. Next, we extract the response-building activity to a separate Responder class. The response-building work turns out to be relatively straightforward: if the asset has a path, that means the service found it, and we should present it as 200 OK; if not, we present it as 404 NOT FOUND.

  3. Last, we rename the Controller to an Action, and name its one-and-only “main” entry point as __invoke(). We modify the code in the Action to (1) invoke the Domain with the incoming request input, (2) place the Domain data into the Responder, and (3) return the Responder.

The end result is three classes instead of one: AssetService to handle Domain work, AssetResponder to handle the response presentation, and AssetAction to handle the incoming request and pass data from the Domain to the Responder.

Compared to the original Controller class, we clearly have more classes, and (aside from the fact that we removed the caching functionality) we likely have somewhat more code as well. But each class, and each method in each class, is relatively short, and the package overall is much more testable:

  • the AssetServiceTest is completely freed up from the Action and Responder (as it should have been in the original MVC code)

  • the AssetResponderTest does not need either the AssetAction or the AssetService, and is able to examine both the body and the headers of the response

  • the AssetActionTest does little more than to check if __invoke() returns a Responder, and see if the assigned data was retained

This separation has the effect of making the underlying components much more independent of each other and a lot easier to test. If we wanted to get really serious we would use interfaces and test doubles to fully isolate the classes.

Right now, some readers are looking at this example and wondering “How is this different from refactoring to a better-separated MVC?” The main difference in this particular example is that, in a webbish MVC setup, the work of setting response headers is generally handled in the Controller. Doing so does not give us as clean a Separated Presentation as we see under ADR. (Remember: on the web, the template is not the view; the response is the view.) In addition, to test the full response (i.e., the headers as well as the body) we would need to run the controller action code instead of just the separated presentation code.

Two final notes:

  • This example is not the only way to do Action-Domain-Responder. The Action could invoke the Responder directly, instead of allowing the calling code to invoke it. The Action might receive a ResponderFactory instead of a Responder object directly. The Responder might receive a ResponseFactory instead of a Response object directly. The Action might just be a closure in a micro-framework route. The point is that we now have a cleanly separated presentation, where the response-building work is completely extracted from the Action, and the Domain work is simiarly completely extracted from the

  • The Action returns a Responder and not a response object; this is predicated on how Aura.Dispatcher works. When the dispatcher invokes a Controller or Action, it checks the return value from that invocation; if that return value is itself invokable, the dispatcher does so recursively until the return result is no longer invokable. This means that the Dispatcher becomes responsible for invoking the Responder returned from the Action; the invoked Responder returns the completed response object.)

That is all; if you have comments on the Action-Domain-Responder paper, please leave them here or as issues out at Github.