In addition to an information architecture and a code base organization architecture (like MVC), we also have the cross-cutting issue of how to distribute the different parts of an app when it is deployed, so we also need a deployment architecture.
Traditionally, most parts of a web app have been executed on back-end computers, while only its HTML/CSS user interface code has been executed on the front-end (or client) side, within a web browser. Today, with the rise of modern JavaScript, we have the option to replace traditional back-end web apps with JavaScript front-end apps, where most parts of the app are executed within a web browser on a front-end device. Such a front-end web app may use either local storage or a (remote) cloud storage service, as illustrated by the two architecture diagrams shown in Figure 6.3.
In both cases, the JavaScript code of the front-end app is loaded
together with its start web page. While using local data storage (with
JavaScript's localStorage
or indexedDB
APIs)
does not require any connection to the Internet after the initial loading
of the app, using cloud storage via HTTP messaging with the
XMLHttpRequest
(XHR) API does require an Internet
connection.
Typically, but not necessarily, a front-end web app is a single-user application, which is not shared with other users.
A back-end web app is a web app where essentially all work is performed by the back-end component, including data validation and user interface page creation. It does not have any front-end component, except the HTML-forms-based, and possibly JS-enriched, user interface pages sent to the user's front-end computer for being rendered by a web browser.
One important task of the controller, especially in back-end apps, is routing: mapping incoming HTTP request messages to a use case of the app, typically represented by a method of a class, such that either the corresponding user interface is provided in the form of a web page or the request message represents the corresponding form submission, which can be directly processed.
Today, with NodeJS, we have the option to deploy the JavaScript components of our app either on the back-end or on the front-end, or on both. In the future, due to WebAssembly, the same options may also be available to other programming languages. Web apps that run the same JavaScript code both on the back-end and front-end have been called "universal" (or "isomorphic"). This is especially useful for data validation code because in a responsive constraint validation approach, as discussed in Chapter 7, we validate user data immediately on input in the user interface, but we also validate it on the back-end before save. Modern JavaScript allows truly distributed apps.
The two diagrams shown in Figure 6.4 illustrate the distinction between the traditional back-end web app architecture and the new architecture of a (truly) distributed web app.