In the previous post, I distilled down into a simple definition what I call the “middle-end” of web applications and also my arguments for why it’s so vitally important that it be a separate and distinct layer rather than an assumed and forgotten tag-along as it is in many common frameworks/platforms.
But upon further discussion and reflection, I realize that it’s tempting to read the ideas I have presented and assume that I’m suggesting a more comprehensive and wide-spread re-architecture effort than I really am. The last thing I would want to do is leave you with the impression that this is an intimidating and complex task to undertake. The tasks I’m advocating for are quite the opposite: they are small, independent, modular, and intended to be rolled into your application in manageable, evolutionary chunks.
So this is just a short follow-up to that post to explain how I feel most web applications could begin the task of redefining their “middle-end” in a more well-formed way, with minimal impact to existing architecture.
The task of re-architecting your middle-end begins with a couple of very simple, incremental steps, not a wide-spread rewrite as it may seem.
Color by numbers
Let’s take data validation for example. First let me define what I mean by data validation: the set of stateless rules which are applied to one or more pieces of data to ensure that the input into the application is safe, reliable, and appropriate.
The most common scenario this is seen in would be form validation. Consider a contact form that requests a visitor’s first and last name, email address, favorite color, and any additional comments. The first and last name fields are text input, and are required. They must both be between 5 and 25 characters. The email field is also text input, must be 8 to 100 characters, and must additionally “look” like a valid email (passing some arbitrarily complex regular expression matcher). The color field is a drop-down, which by virtue of the UI paradigm is constrained to a pre-defined set of options. The additional comments are optional, but if present must not contain any HTML.
Stateless Data Validation
Data validation in this context would entail all of these aforementioned rules. It could also entail data integrity checks, like for instance asking something (totally contrived for this discussion) like “if the first name is John, the last name cannot be Brown”.
However, something like enforcing that the email address was “unique” in our database (meaning we’ve never heard from this person before), or that the email was not already on a blocked “black list” as a spammer — those tasks would not be stateless data validation checks, but would instead require stateful back-end business logic. That would not be something we’d want to do wholly in the UI layer (maybe via a round-trip Ajax request, etc).
The point is that stateless data validation/integrity checks are agnostic of the environment or the state of the application. The check is blindly applied to a piece of data, and the result is binary true or false — either it passed or it didn’t. This means that such code can be written to act upon a data structure (like JSON) and be completely ignorant of where the data came from. This is very important.
This is where trouble usually starts happening. We re-write all our validation rules a second time, this time in another language like PHP or Java. We’ve made a second copy of that code/logic, and we’ve forever cursed ourselves with more complicated code maintenance.
On the server, you would take inbound data, either already formatted as JSON (preferably) or in key-value pairs that you could easily serialize to JSON, and then pass that inbound data directly into the same code.
This still seems complex
If you get a “true” back, the data validation passed, and your application can continue as necessary. If “false” (or some other specific error messaging, if you prefer), then immediately respond back to the request with the error and don’t let the application continue.
The rabbit hole
Data validation is only one of the dozen or so tasks that the “middle-end” entails. Your next step might be to start tackling DRY approaches to templating. Again, you should go little-by-little into that world.
Regardless of how you proceed, I hope it’s clear now that I advocate a pattern rather than particular implementation details, and that I advocate little baby steps along the path, rather than complex and comprehensive re-writes. That I believe is the right path to beginning your middle-end.