Paul M. Jones

Don't listen to the crowd, they say "jump."

Semantic Versioning and Public Interfaces

Adherence to Semantic Versioning is just The Right Thing To Do, but it turns out you have to be extra-careful when modifying public interfaces to maintain backwards compatibility. This is obvious on reflection, but I never thought about it beforehand. Thanks to Hari KT for pointing it out.

Why do you have to be extra-careful with interfaces and SemVer? To see it more clearly, let's use a concrete class as an example.

class Foo
{
    public function bar() { ... }
    public function baz() { ... }
}

If we remove a public method, that's clearly a BC break. If we add a non-optional parameter to an existing public method, that's also clearly a BC break. Those kinds of changes will break any code already using the Foo class; that code will have to be modified to accommodate the changes in Foo.

However, if we add a new public method to the concrete class, that is not a BC break. Likewise, changing the signature of an existing method to add an optional parameter is not a BC break either. (UPDATE: See note below.) Code using the Foo class does not have to change to accommodate the new method or the new optional parameter.

But what happens with an interface?

interface FooInterface
{
    public function bar();
    public function baz();
}

Removing a method, or adding a non-optional parameter to an existing method, is the same as with a concrete class: it's BC break.

However, unlike with a concrete class, adding methods is also a BC break. So is changing an existing method sigature to add an optional parameter. Existing code that implements FooInterface will no longer comply with the interface; that code will have to change to accommodate the new method or the new optional parameter.

Thus, interfaces are more susceptible to BC breaks than concrete classes. Once an interface is published as "stable", I don't see how it can be changed at all per the rules of SemVer (that is, unless you bump the major version). The only thing you can do to maintain BC is add an entirely new interface to the package while leaving the old one in place, perhaps even extending the old one if needed.

Again, it's obvious in hindsight, but I did not have the foresight to anticipate it. Perhaps this realization will save you some trouble in the future.

p.s. On further examination, the interface constraints apply to abstract classes, too. Changes to an abstract mean that child classes will have to be modified as well, otherwise they won't comply with the modified abstract.

UPDATE: Dave Marshall notes on Twitter that in the concrete class case, if you add an optional parameter to a method, and a user has extended and overridden that method, the extended class will break under PHP E_STRICT. He links to Symfony policy on the subject, which I will now have to read.



Radar: Answering Questions, and New Middleware

Last week’s announcement of Radar, an implementation of Action-Domain-Responder using PSR-7, was a resounding success. The feedback has been mostly positive, with some confusion and misunderstanding, and with one particular question being raised more than once.

This Reddit thread is typical of the various questions and comments I’ve received so far:

[“ADR” is just] the hipster slang for ‘c’, ‘m’ and ‘v’.

In other words, “Why ADR in the first place, and not just MVC?” This is answered by the ADR white paper, and again by some commentary here. In short, ADR is a refinement of “web” MVC to more accurately describe how we actually work in a request/response environment. The renaming of the components is intended to break the association with “real” MVC. (Special thanks to “lordofworms” for his patient and civil responses to the questioner.)

Why [is the project called] “Radar”?

As noted in the Reddit thread by others, “Radar” is a sound-alike from the ADR acronym. (An early version of the ADR paper was titled Request-Action-Domain-Response, the acronym for which lends itself even more to “Radar”, and I had that in mind too.)

why use classes at all? If most of your classes contain a single __invoke method, could they not just be substituted with namespaced functions?

The questioner was answered quite thoroughly on Twitter. I will add only that there’s nothing about ADR that says you must use classes. If you can implement ADR using all functions all the time, go for it. ADR is a pattern, not an implementation; Radar is an implementation, not a pattern.

Finally, we have this very good criticism referring to the middleware implementation:

Passing arguments by reference will confuse users.

Variations on this theme came up elsewhere as well. As a result, I have re-worked the middleware implementation completely.

Previously, Radar used a “filter” style of middleware, where an iterator calls each middleware handler in turn at different points in the execution path. This is the style used by Slim 2 and Silex, and works well with globally mutable request and response objects.

However, PSR-7 requests and response are immutable. I have not previously used immutables very much, and I tried to subvert the immutability by allowing middleware to use reference parameters. The references would make the request and response objects appear globally mutable, even though the objects were in fact immutable.

The critics who noted that this was potentially confusing, as well as a subversion of the immutable intent, turned out to be worth listening to. I experimented a bit with a wrapper-style (or chain-style) of middleware, and I’m much happier with it.

In the new implementation, each middleware calls the next one in turn, instead of an external iterator looping over them. (There is a Dispatcher object that “holds” the queue of handlers, and that it what gets passed to each handler for its $next call.) I got the idea from reading MWOP’s Conduit code, although this is greatly pared down from that. You can read more about the new implementation here.



Radar: A PSR-7 Action-Domain-Responder Framework

Radar is a PSR-7 compliant Action-Domain-Responder (ADR) system. While it may look like a micro-framework, it is more like a wrapper around the real core of your application domain. Its architecture makes it an excellent complement to Domain Driven Design.


Radar is superficially similar to a micro-framework. It has a routing system to point URLs to actions, a filter-style middleware system to modify the incoming HTTP request and outgoing HTTP response, and a dependency injection container and configuration system to wire everything together.

However, with Radar, you don’t specify “controllers” or “closures” for your routes. Instead, you specify up to three callables per route, all of which are optional:

  1. A Domain callable to be invoked with the user input. (If you don’t specify a Domain callable, the Responder will be invoked directly; this is unusual but sometimes convenient.)

  2. An Input callable to extract user input from the incoming HTTP ServerRequest. The default Radar Input callable will naively merge the route path attributes (path-info parameters), the query parameters ($_GET), the parsed body parameters ($_POST), and the uploaded files array ($_FILES) into a single associative array of user input.

  3. A Responder callable to convert the Domain output to an HTTP response. The default Radar Responder expects a Payload object from the Domain; it delivers JSON output and sets proper HTTP status codes for a wide range of scenarios.

These three callables are invoked within a standardized ActionHandler. As a result, the Action logic in Radar is always the same for every route. The only variations are in how input is collected, how output is presented, and of course in how your core application domain operates.

So, don’t think of Radar as a micro-framework. Think of it more like a wrapper around the core of your real application domain. Its only purpose is to guide input from the user into the domain, and to present output from the domain back to the user.

You can read the documentation for it here.



A PSR-7 Web Router Implementation, and Bookdown Documentation

From the Aura blog:

Our first 3.x package is now available for review, a PSR-7 implementation of Aura.Router. It includes some feature upgrades such as custom rules and more powerful route definitions.

...

On a side note, the package documentation uses Bookdown for its documentation. You can see the generated documentation here. Bookdown allows us to keep documentation sources in each library repository. We can then collect them all into a single “book” on the Aura site using a bookdown.json file with remote “content” elements.

Read the rest at the Aura blog.



Separate The User Interface Repository From The Core Application Repository

tl;dr: Keep the core application (“model”, “domain”) code repository separate from the user interface (“controller/view”, “action/responder”) code repository; use a dependency manager in the user-interface repo to bring in the core-application repo.


Nihal Sahu asked on Twitter, “How do you ‘personally’ go about building an application? What Structure?” This post is my longer-than-140-characters response.

Obviously I’m a fan of Action-Domain-Responder as a pattern for web-based user interfaces. (ADR treats the request/response cycle itself as a user interface. The HTML/CSS/JS/etc that goes into the HTTP body is just one part of the presentation half of the user interface; ADR reminds us that the HTTP headers are part of the presentation, too.)

But ADR, and MVC, and the other user-interface patterns – they are not an application architecture in and of themselves. The “Domain” in ADR and the “Model” in MVC are just entry points into the underlying core of the overall application architecture. In a way, the “Action/Responder” and “Controller/View” portions of the UI are not the big deal in the application; the big deal is the underlying core. That’s where the real work happens.

With that in mind, one first thinks the right approach would be to separate the User Interface from the Core Application. This is obvious and uncontroversial; separation of concerns is a central tenet of good architecture.

What might be controversial is my extended advice regarding that approach. I don’t suggest a merely “logical” separation of concerns so that Action/Controller classes don’t have Domain/Model code in them. I suggest a “physical” separation. In other words:

Separate the User Interface repository from the Core Application repository.

Yes, I mean that you should have two code repositories for your application. Let’s explore that idea for a minute.

The first repository, the Core Application one, contains no user-interface code at all. No HTTP, no standard input/output, nothing. It expects to receive input in an interface-independent way, and it delivers output in an interface-independent way. Note that it receives the input. It has to be sent to the Core Application in some way, not read from the interface (no superglobals!). The injected input could be via method parameters, a plain old PHP array, an input object provided by the Core Application, a Command object provided by the Core application, etc. Likewise, the output could be via anything provided by the Core Application, such as a Model object, a Domain Payload, or something else. It is completely independent from any user interface code and can be tested on its own.

The other repository, the User Interface one, contains your “Action/Responder” or “Controller/View” (or “Command/Stdout”) code. There is no business logic at all. All it does it reformat the user input to something the Core Application will recognize, pass it to the Core Application, and receive back some output from the Core Application, which it reformats for presentation to the user.

But if the two repositores are “physically” separated, how can the User Interface get access to the Core Application? Composer becomes your best friend in this case. In the User Interface codebase, add "require": { "project-name/core-application": "dev-develop" } to composer.json. Issue composer update and voila: your Core Application is now available to the User Interface. The User Interface depends on the Core Applicatiion, but the Core Application has no dependency on the User Interface.

What’s great about keeping the repositories fully separated from each other is that it enforces developer discipline. It becomes difficult to put Core Application code in the User Interface code. Any attempts to do so are immediately obvious, and everyone watching can see it happening. It becomes harder to justify to yourself “I’ll add it just this one time” (and thus keeping off that particular slippery slope).

The tradeoff is that you now have to coordinate changes across two code repos. Breaks in the Core Application will break the User Interface. The disconnection can be a positive overall, since you can version the Core Application separately from the User Interface, but in practice it does mean you have to be more attentive to change management.

One more thing about keeping the User Interface “physically” separate from the User Interface in this way is that you start thinking differently about frameworks. I have begun to think that our vocabulary for describing frameworks in PHP land is insufficiently varied. MVC and ADR do not describe “application frameworks” – they might describe User Interface frameworks, but there’s no word for Core Application frameworks. Maybe they need their own separate framework term.



Aura 3 Plans

From the Aura blog:

  • The Past

    • Aura 1.x framework packages will see no new releases, and may be archived.

    • Aura 1.x library packages are near the end of active development; to prevent orphaning and end-of-life, ownership and authority over them they may be transferred to interested parties.

  • The Present

    • Aura 2.x packages that are currently stable will remain the center of development attention, with some modifications to Composer and PHPUnit support files, and with added testing on PHP 7.

    • Aura 2.x packages that are not currently stable will not see stable 2.x releases; they will become 3.x candidate packages.

  • The Future

    • Aura 3.x packages will target PHP 5.6, and additionally test on PHP 7.

    • Aura 3.x library packages will be allowed to depend on interface packages, though not other implementation packages.

    • Aura 3.x will not provide a framework under the Aura name, although the 2.x framework should be able to use 3.x components. Frameworks of Aura packages may be provided as separate projects.

    • Aura 3.x and later packages will have independent major version release cycles.

Read the entire post here.


Using Aura.Html with League\Plates

Aura has its own native PHP template package, Aura.View, a direct descendant of Savant and Solar_View, as well as a cousin to Zend_View.

The v1 Aura.View package used to include a helper system. Once we realized that there was no reason to tie the helper system directly to the view system, we released the helpers as a standalone Aura.Html package. This means the helpers can be used in any PHP presentation code, framework-based or otherwise.

As an example, let’s try integrating the helpers with Plates, a relative newcomer in the native PHP templating world. Plates allows you to register functions with its template engine, which means we can pull individual helpers out of Aura.Html and drop them into Plates, like so:

<?php
$plates = new League\Plates\Engine('/path/to/templates');
$helper = (new Aura\Html\HelperLocatorFactory())->newInstance();

$plates->registerFunction('anchor',     $helper->get('anchor'));
$plates->registerFunction('anchorRaw',  $helper->get('anchorRaw'));
$plates->registerFunction('base',       $helper->get('base'));
$plates->registerFunction('form',       $helper->get('form'));
$plates->registerFunction('img',        $helper->get('img'));
$plates->registerFunction('input',      $helper->get('input'));
$plates->registerFunction('label',      $helper->get('label'));
$plates->registerFunction('links',      $helper->get('links'));
$plates->registerFunction('metas',      $helper->get('metas'));
$plates->registerFunction('ol',         $helper->get('ol'));
$plates->registerFunction('scripts',    $helper->get('scripts'));
$plates->registerFunction('styles',     $helper->get('styles'));
$plates->registerFunction('tag',        $helper->get('tag'));
$plates->registerFunction('title',      $helper->get('title'));
$plates->registerFunction('ul',         $helper->get('ul'));
?>

Now you can use the tag helpers and form-building helpers from Aura.Html in your Plates templates. For example, if your Plates template looks like this …

<html>
<head>
<?= $this->title('My Title'); ?>
</head>
<body>
<p>Try out <?= $this->anchor(
    'https://github.com/auraphp/Aura.Html',
    'Aura.Html'
); ?>
with <?= $this->anchor(
    'http://platesphp.com',
    'Plates'
); ?> !</p>
</body>
</html>

… it will render to:

<html>
<head>
    <title>My Title</title>
</head>
<body>
<p>Try out <a href="https://github.com/auraphp/Aura.Html">Aura.Html</a>
with <a href="http://platesphp.com">Plates</a> !</p>
</body>
</html>

Try out Aura.Html today, and see how much you like it with your output system of choice. (We’re partial to Aura.View for that task, but then, we would be.)

UPDATE: As usual, Hari KT is ahead of the curve with his post on this same topic from a year ago: http://harikt.com/blog/2014/05/13/extending-plates-with-aura-html-helpers/.

UPDATE 2: Someone asked how easy it is to use Aura.Html with Aura.View. It's 3-lines-easy: see https://github.com/auraphp/Aura.View#custom-helper-managers.




A New Book About The N+1 Problem, and an Update to MLAPHP

I’ll have a new book finished and ready for you soon: Solving the N+1 Problem in PHP. Although I have written and spoken about the N+1 problem several times over the past few years, this book is an extended disstertation on the topic.

Describing the N+1 problem is one thing, and talking about the solutions in the abstract yet another. But how to diagnose and discover the problem, as well as refactoring strategies to resolve N+1 problems in your codebase? Those are something else, and they are what the new book provides, similar to the strategies I presented in Modernizing Legacy Applications in PHP. At about 40 pages of narrative and code, in many ways the new N+1 book serves as a topic-specific add-on to MLAPHP.

Speaking of which, MLAPHP is getting an update! The update is nothing extensive, mostly typo fixes and a couple of added details, all from attentive and interested readers. Current owners will receive the update for free.

So when will they be completed? Monday. And there’s a special deal involved for the week they’re finished.

MLAPHP is just about a year old, so to celebrate this new book, if you purchase both MLAPHP and the N+1 book as a bundle next week, they will each be about 50% off. That’s a total of $23.99 $22.99 (suggested $39.99 $28.99) for both books, with a 45-day money-back guarantee backed by Leanpub.

After the sale week, they’ll go back to their normal prices, so this is your chance to get a bigger bang for your buck. Of course, the new N+1 book is only $5.99 (suggested $7.99), so it’s not exactly a bank-breaker in the first place.

More updates when the new book and the update are finalized!

UPDATE (Fri 20 Mar): The bundle is now available at https://leanpub.com/b/mlasn1php. Go get it while you can!


I'm not anti-intellectual; I'm anti-intelligentsia.

One kind of “anti-intellectualism” is opposition to “intellectuals” considered as an interest group or social class in the Marxian sense – what Russian writers called the intelligentsia. The only more specific term I can think of for this is anti-intelligentsianism, an ugly coinage which will have to do for the duration of this essay.

...

The intelligentsia has displayed a consistent political pattern over the last 150 years: believing in its own intellectual and moral superiority, it has sought a leading role in politics, promoting a vision of itself as benign philosopher-kings who can steer society to virtue, equality, and fulfillment.

The vehicles of this belief have been many. At its worst, it has led the intelligentsia to endorse and propagandize for totalizing systems like Communism, which the intelligentsia conceived could be guided to good ends in its use of power by – who else? – intellectuals. It is forgotten, but true, that before World War II many intellectuals were attracted to Fascism for the same reason. In this way much of the intelligentsia of the 20th century became accomplices in and apologists for the most hideous mass murders in human history.

Via The Varieties of Anti-Intellectualism, worth reading in its entirety. (it gives voice to part of what I mean when I say "It's not enough to be smart; you have to actually know things.")