{
    "href": "/post/2015/03/31/separate-the-user-interface-repository-from-the-core-application-repository/",
    "relId": "2015/03/31/separate-the-user-interface-repository-from-the-core-application-repository",
    "title": "Separate The User Interface Repository From The Core Application Repository",
    "author": "pmjones",
    "markup": "html",
    "tags": [
        {
            "href": "/tag/adr/",
            "relId": "adr",
            "title": "Action Domain Responder",
            "author": null,
            "created": "2020-08-17 21:07:42 UTC",
            "updated": [
                "2020-08-17 21:07:42 UTC",
                "2020-09-22 15:41:16 UTC",
                "2020-10-14 18:20:29 UTC",
                "2020-10-14 18:36:31 UTC",
                "2020-10-14 18:36:53 UTC",
                "2020-10-14 18:37:08 UTC",
                "2020-10-14 18:37:48 UTC",
                "2020-10-14 18:39:26 UTC",
                "2020-10-14 19:03:17 UTC",
                "2020-10-14 19:03:35 UTC",
                "2020-10-26 18:12:53 UTC"
            ],
            "markup": "markdown"
        },
        {
            "href": "/tag/php/",
            "relId": "php",
            "title": "PHP",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/programming/",
            "relId": "programming",
            "title": "Programming",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        }
    ],
    "created": "2015-03-31 16:26:31 UTC",
    "updated": [
        "2015-03-31 16:26:31 UTC"
    ],
    "html": "<p>tl;dr: Keep the core application (\u201cmodel\u201d, \u201cdomain\u201d) code repository separate from the user interface (\u201ccontroller/view\u201d, \u201caction/responder\u201d) code repository; use a dependency manager in the user-interface repo to bring in the core-application repo.</p>\n<hr>\n<p>Nihal Sahu <a href=\"https://twitter.com/codenihal/status/581875458423189504\">asked on Twitter</a>, \u201cHow do you \u2018personally\u2019 go about building an application? What Structure?\u201d  This post is my longer-than-140-characters response.</p>\n<p>Obviously I\u2019m a fan of <a href=\"http://pmjones.io/adr\">Action-Domain-Responder</a> 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.)</p>\n<p>But ADR, and MVC, and the other user-interface patterns \u2013 they are not an application architecture in and of themselves. The \u201cDomain\u201d in ADR and the \u201cModel\u201d in MVC are just entry points into the underlying core of the overall application architecture.  In a way, the \u201cAction/Responder\u201d and \u201cController/View\u201d portions of the UI are not the big deal in the application; the big deal is the underlying core. That\u2019s where the real work happens.</p>\n<p>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.</p>\n<p>What might be controversial is my extended advice regarding that approach. I don\u2019t suggest a merely \u201clogical\u201d separation of concerns so that Action/Controller classes don\u2019t have Domain/Model code in them. I suggest a \u201cphysical\u201d separation. In other words:</p>\n<p><strong>Separate the User Interface repository from the Core Application repository.</strong></p>\n<p>Yes, I mean that you should have two code repositories for your application. Let\u2019s explore that idea for a minute.</p>\n<p>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 <em>receives</em> the input. It has to be <em>sent to</em> the Core Application in some way, not <em>read from</em> 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 <a href=\"http://paul-m-jones.com/archives/6043\">Domain Payload</a>, or something else. It is <em>completely independent</em> from any user interface code and can be tested on its own.</p>\n<p>The other repository, the User Interface one, contains your \u201cAction/Responder\u201d or \u201cController/View\u201d (or \u201cCommand/Stdout\u201d) 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.</p>\n<p>But if the two repositores are \u201cphysically\u201d separated, how can the User Interface get access to the Core Application?  <a href=\"https://getcomposer.org\">Composer</a> becomes your best friend in this case. In the User Interface codebase, add <code>\"require\": { \"project-name/core-application\": \"dev-develop\" }</code> to <code>composer.json</code>. Issue <code>composer update</code> 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.</p>\n<p>What\u2019s 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 \u201cI\u2019ll add it just this one time\u201d (and thus keeping off that particular slippery slope).</p>\n<p>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.</p>\n<p>One more thing about keeping the User Interface \u201cphysically\u201d 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 \u201capplication frameworks\u201d \u2013 they <em>might</em> describe User Interface frameworks, but there\u2019s no word for Core Application frameworks.  Maybe they need their own separate framework term.</p>\n<hr>\n<p class=\"reddit-links\">Read the Reddit discussion about this post <a href=\"https://www.reddit.com/r/PHP/comments/30xw9g/separate_the_user_interface_repository_from_the/\">here</a>.</p>\n"
}
