By Greg Trasuk on March 7, 2017
In the Beginning
We've been writing web applications, particularly Java-based applications, for
many years now. Most architects are comfortable with MVC-based frameworks
like Struts or Spring. Many have used component-based frameworks like Java
Server Faces. We've used the Java Enterprise Edition to handle "Enterprisey"
non-functional requirements, like security, transactionality, scalability, etc.
These frameworks are well-understood, reliable, well-tested, and increasingly,
looking a little dated.
The reason is the level of interactivity that users now expect in a web application.
Our traditional way of interacting involved having the user fill in a form, and
then "submit" that form. Clicking "submit" caused the browser to send all the
form fields up to the server. The server would take the input, process it, and
then send an updated screen down to the browser. Apart from images, it wasn't
that much different from using an old-school IBM3270 green-screen "form-based"
terminal. Only on the terminal, there was a physical "submit" button.
The tradeoff of web applications versus desktop applications was one of
usability versus manage-ability. The web app was much less usable, but the
management load was greatly reduced, since we didn't need to install the web app
on the user's machine. The app was effectively downloaded page-by-page, as needed.
All that changed around 2004, when Google unleashed Gmail on the world, followed
in 2005 by Google Maps. Here for the first time, the world was presented with
serious applications using "Dynamic HTML", and "AJAX" techniques. We could
no longer ignore the fact that the browser was a complete computing environment.
The New Standard Architecture
System architecture largely involves drawing boxes around things, and then
figuring out how to connect the boxes. Technically, we'd call this
"establishing system boundaries", "decomposing into subsystems and components", and
"designing the interface between components".
But the point stands: Once we can start drawing a few boxes around things, and
figuring out how we talk across those boundaries, we're moving rapidly towards
a completed architecture.
In the case of a rich web application, the first box is drawn for us - it's the
inside the browser. Eventually, you'll need to select a technical architecture
for that application (i.e. AngularJS, Angular2, React, or whatever), but the
core proposition is that the browser executes an application. It's probably
worth mentioning that the same idea holds if the UI runs on a mobile device (
phone or tablet) rather than a browser.
The browser application has some constraints - it basically can't do anything
with the local file system, and it's constrained to interact with the server
that served out the original application (this is the browser sandbox, and the
same-origin policy). That determines the next box that we need to draw - UI
The nature of the browser also determines the characteristics of the
interface that crosses the boundary between the UI device and the UI services.
There are really only two options: http (most likely RESTful API) or Web Sockets
(more options, but probably just exchanging JSON objects).
Now, we could go ahead and put all the business logic into our "UI Services"
box, and let it talk to the storage. There are at least two reasons not to do
- It's entirely possible that different devices might need different UI services.
- We've spent 20 years saying that business logic should be separated from UI
code. Why change now?
There's another good question to be asked - "Who writes the code inside these
boxes?" Especially in an enterprise scenario, you might have different groups
writing these components; creating decent UI's is a whole different skill set from
understanding and coding a bank's complicated business logic.
So... the final, minimal architecture looks something like this, if we assume
the business logic talks straight to the storage.
In the next installment, we'll talk about the communications between those boxes,
and what goes inside them.