Coldfusion server-side validation

jdavidb on 2004-12-06T16:51:26

ColdFusion's server-side validation system has a terrible design problem. In order to add a constraint to an HTML form field, you define an additional hidden HTML field with the same name and append to the name an underscore and one of the constraint options. For example, to make form field USERNAME required, you define hidden form field USERNAME_REQUIRED. To require form field START to be a valid date, you define hidden form field START_DATE. Then when the server receives the forms, it follows the maxims in the hidden form fields.

The reason this is terrible is it violates the fundamental tenet of HTTP server-side programming: never assume you have any control at all over what the client submits to you. You absolutely must be paranoid about what you get back from an HTML form, because you have no idea what happened. The form you sent could have been mangled, and your fields didn't get defined right (or at all). The form could have been bookmarked from three years ago, and the previous version didn't contain all your fields. The user could be malicious or incompetent and edited a local copy of the page to remove restrictions and allow his data to be submitted. ("I know it says this field must be a date, but this item doesn't have a date, and we need a place to put the circuit ID, so I'll just put it in here.") And a fact lost on many inexperienced programmers is that the form they coded may not be used to submit data at all: another programmer may be writing a script to automate submission. Training yourself to rely on this kind of validation may only result in inconsistent data in your database, disaster enough in itself. But far worse, if you rely on it for security, you may make yourself an easy target.

This is also the reason Javascript client-side data validation "doesn't work." (Actually it does work; it's just that you can't rely on it to do what people want it to. You can save a trip to the server by having Javascript validate the data first, but you better still code your server-side program to be paranoid and assume ABSOLUTELY NOTHING about the form data it receives, because you still don't know what will happen. Users have been known to save web pages and file off the Javascript validation. And for those of you insisting that your users are not competent enough to do that, have you given any thought to the fact that your users' incompetence may cause something even worse and far more unpredictable to happen? You absolutely cannot trust the client side.)

So it's nice for the server to build in this kind of validation feature (even though it's limited enough it's probably still not useful for much work), but the information about whether a field is required and what constraints it must have must be encoded into the server-side program itself rather than the client-side.

Think about design for a minute. When you define an RDBMS table, you are supposed to include the constraints for the table with the table in the database itself. If you try to enforce your constraints in your code instead of on the table, you are using a recipe for disaster. The same principle holds here. (Who's to say that next year you don't code an alternative form for your server-side program, so that your program now has two entry points, with two different sets of field constraints to get out of sync.)

I know the temptation is to feel that the requirements for the form fields ought to be in the form itself. That's a siren song trying to lure you into a trap. It seems to make good design sense, but for the reasons outlined above, it's a bad idea. HTML is not a clean enough place with enough features for you to use as the one single source of information about your form. If you absolutely want one universal place to define your form, here's what you should do: define a file format for defining your form (perhaps XML or perhaps something simpler). Include in this little mini-language the ability to specify your constraints or whatever. Then write your server-side program to read this form definition to see what variables to expect and what constraints to check for, and write a program to dynamically generate your HTML form by looking at the same definition file.