By Peter Bell

Introducing the Input Object

All of the major MVC frameworks have some way of providing access to the URL/form scopes as a single scope. In LightBase, we use an object with generic getters and setters (why are you not surprised!) but we also add a little more power to solve another common issue with input variables . . .

Anyone remember the old days when we had pages that could be accessed by a URL or a returning form and so we had the following code (or something that solved essentially the same problem) everywhere?

<cfif IsDefined("Form.ID")>
   <cfset URL.ID = form.ID>
</cfif>

Often the next step was to add a cfparam or an if statement so if a variable didn't exist in either form or URL state it would be set to a default value so you didn't have to keep writing "IfDefined" throughout your code. Of course, in each of these cases you are losing information (such as whether the variable exists and *which* scope it came from) but it is quite possible to build sites that don't need those pieces of information and that is the way that (I believe) the majority of apps are now written.

Frameworks from Fusebox onwards have taken care of this plumbing for us automatically, but they don't think in terms of data types, so they still leave us to handle validation of well formed control inputs.

Control vs. Data
I make a distinction between two different types of inputs in the URL/form scopes - control inputs and data inputs. Data inputs are typically things like User.FirstName or Product.Price and are used to affect the values of objects. Control inputs are things like CategoryID or event or mode that are used to direct the object to edit, the page to display or the controller method to perform.

Validation of data inputs (anything that will be loaded as data into a business object bean - a User or a Product or a Category or whatever) should be carried out by the bean itself (probably using composition, but it is fundamentally the beans responsibility to be able to validate its values). But how do you handle validation of control inputs? For instance if you use a CategoryID to get the category to view, it is really a best practice to validate that it isNumeric and/or to make it numeric long before you pass it to your cfqueryparam in your SQL call. It is a matter of defense in depth.

With the Input object, you can define the data types of known control variables which means it can automatically validate the variables as numerics or whatever and handle either throwing an error or returning an acceptable null response. For example, in the past I've often just RegEx'd potential ints to have only 0-9 and if len() 0 after Regex, replace by 0. There are many other ways of solving the problem (and I'd like to get some input on how other people specifically validate and handle invalid integer control inputs) but it gives the idea.

I still really haven't locked the interface for documenting the control variables in the input object - I have working code, but it isn't exactly where I want it to be yet. That said, the basic approach works well and means I get automatic validation in the input object of my control variables and (if I wanted to implement a strict mode) could probably even force all input control variables to be defined in the input object to make for an extremely self documenting application (although it'd be an optional mode if I implemented it).

Again, any thoughts much appreciated!

Comments
BlogCFC was created by Raymond Camden. This blog is running version 5.005.