Paul M. Jones

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

Technical Speaker Uninvited When SJWs Politicize Event

Latest hullaballoo: Curtis Yarvin (aka “Mencius Moldbug”) was invited to give a presentation on his new computer system Urbit to the Strange Loop tech conference. Then some of his ideological enemies (actually literal Communists) found out, objected to his political views, and he got banned from the conference.

Article here, Hacker News thread here, impressively prescient Moldbug post here, demonstration of inevitable Streisand Effect here.

I did consider not linking this since it’s so obviously toxoplasma, but I was convinced to do so by this letter where the conference organizer states he’s never read any Moldbug himself, but decided to cave to the ban request because otherwise politics overshadow the conference, which was supposed to be about tech.

This kind of crystallizes a pattern I’ve been noticing recently where some social justice activists use a tactic along the lines of “Nice institution youse gots here, shame if somebody were to politicize it”.

I sympathize with the desire to give into that to avoid trouble, but I think maybe the only way to avoid enshrining that kind of heckler’s veto always working is to make it clear that the choice to give in will also be politicized.

Maybe if organizers know that banning all insufficiently-leftist-people and not banning all insufficiently-leftist-people will both result in politicization and Internet firestorms, they’ll say “screw it” and just follow their principles.

Via Slate Star Codex. Apparently you're not allowed to speak about anything at all if you don't have The Right Political Opinions At The Right Time, especially when the #hashTagMob start bullying and heckling. The best response to the #hashTagMob is to double down and invite *more* people they disagree with. Giving in gives them the ability to say "See, we were right!" and then they'll do more of it. Once you pay extortion, you never get rid of the extortionist.


Relay: A PSR-7 Middleware Dispatcher

UPDATE (2015-06-09): Due to a conflict with the "pipeline" design pattern name, which this project does not implement, the project name has been changed from Pipeline to Relay. Links and naming have been updated inline, with the original text block quoted beneath.

In a fit of inspiration over the weekend, I extracted the middleware dispatcher from the Radar ADR core into its own standalone library: Relay. If you need to execute a queue of middleware, Relay is for you.

Relay uses a common PSR-7 middleware signature: function ($request, $response, $next) and return $response. That is what Slim 3 uses, along with Stratigility and Radar, and is modeled on Sencha Connect. Any callable/invokable with that signature will work with Relay.

As a standalone library, Relay is framework-independent, so you can use it anywhere. You could even build your own framework around it, picking a dotenv-loader of your choice, a DI container of your choice, and a middleware queue of your choice.

Speaking of DI containers, Relay is also container-independent. You can use any dependency-injection system you like to build your middleware queue and pass it to Relay. All you need to do is pass in a callable that converts each queue entry to an object or callable. Try it with PHP-DI, Pimple, Auryn, or even Aura.Di.

I have converted Radar to use Relay at its core, and soon I'll be extracting two of the basic Radar middleware classes to standalone packages. When I do, they'll be listed on the Relay wiki.

ORIGINAL RELEASE:

In a fit of inspiration over the weekend, I extracted the middleware dispatcher from the Radar ADR core into its own standalone library: Pipeline. If you need to execute a queue of middleware, Pipeline is for you.

Pipeline uses a common PSR-7 middleware signature: function ($request, $response, $next) and return $response. That is what Slim 3 uses, along with Stratigility and Radar, and is modeled on Sencha Connect. Any callable/invokable with that signature will work with Pipeline.

As a standalone library, Pipeline is framework-independent, so you can use it anywhere. You could even build your own framework around it, picking a dotenv-loader of your choice, a DI container of your choice, and a middleware queue of your choice.

Speaking of DI containers, Pipeline is also container-independent. You can use any dependency-injection system you like to build your middleware queue and pass it to Pipeline. All you need to do is pass in a callable that converts each queue entry to an object or callable. Try it with PHP-DI, Pimple, Auryn, or even Aura.Di.

I have converted Radar to use Pipeline at its core, and soon I'll be extracting two of the basic Radar middleware classes to standalone packages. When I do, they'll be listed on the Pipeline wiki.



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.