Design Validation – Managing Client-Side and Server-Side Validations in One Place

client-serverdesigndryvalidation

I'm 100% on board with the case that one should definitely use both client-side and server-side data validations.

However, in the frameworks and environments I've worked in, the approaches I've seen have never been DRY. Most of the time there's no plan or pattern – validations are written in the model spec, and validations are written in the form on the view. (Note: Most of my first-hand experience is with Rails, Sinatra, and PHP w/ jQuery)

Mulling it over, it seems like it would not be difficult to create a generator which, given a set of validations (e.g. model name, field(s), condition), could produce both the necessary client-side and server-side material. Alternately, such a tool could take the server-side validations (such as the validates code in an ActiveRecord model) and generate client-side validations (such as jQuery plugins, which would then be applied to the form.

Obviously, the above is just a "hey I had this idea" musing, and not a formal proposal. This sort of thing is surely more difficult than it seemed when the idea hit me.

That brings me to the question: How would you approach designing a "write once, run on server and client" technique for data validation?

Related subtopics: Do tools like that exist for any particular frameworks or client-server technologies? What are major gotchas or challenges with trying to maintain only one set of validations?

Best Answer

In my limited experience, the points where validation are required are

  1. The presentation level using HTML,
  2. at the post-presentation level (i.e., Javascript validation),
  3. at the combination level where interactions between multiple fields have to be validated together,
  4. at the business logic level and
  5. at the database level.

Each of them have different languages, timings, and triggers. For instance, it makes little sense to validate a field before the entire record is in a consistent state, unless you want to validate just one piece. Constraints at the database level have to be applicable only at the end before a commit, and cannot readily be done piece-wise.

A related concept is that representing data varies between each of the levels. A simple example is a web browser represents a piece of text as, perhaps, CP1290, while the database represents it in UTF-8; the lengths of the two strings differ so enforcing length constraints gets awkward.

Related Topic