Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at cf.Objective() 2013 (Bloomington, MN) with:

Final Thoughts On CFParam And Data Type Validation

Posted by Ben Nadel
Tags: ColdFusion

Last week, I wrote about Data Type validation versus Data Value validation. I claimed that ALL of your data type validation should be done by ColdFusion's CFParam tag before you do any other data validation or business logic. When I mentioned this to Javier Julio, he challenged me on this. He asked, "What does that give you? If you're already doing the type validation with the value validation, why bother separating it out?" I mumbled something about separation of concerns, but then hurriedly moved the conversation on. To be honest, I wasn't ready to formally defend my opinions on this matter.

But, a week has gone by and I have had much turkey and beef to fuel the machinery and I feel that now, I am able to briefly discuss why I would move the data type validation to the top of your form processing pages. In a single word, convenience. It is simply more convenient to have data type validation done before your data value validation.

This concept does not become immediatly apparent because we are so used to dealing with FORM data in a single pass. When I started thinking about CFParam, in my gut, I only had a feeling for what I was not able to express until some back and forth comments with Sean Corfield. It was in these comments that I was able to codify what I was feeling: your form processing page is, in its own right, just like a user defined function.

Instead of thinking of your page like this:

  • <!--- Param data. --->
  • <!--- Process data. --->

... think about it like this:

  • <cffunction>
  • <!--- Param data. --->
  • <!--- Process data. --->
  • </cffunction>

Because, isn't that really what we are doing? We are submitting data to an action template for processing. The action template doesn't display anything. It just accepts data, processes it, and sets some variable to be used later on in the page flow. Sounds kind of like a function or sub-routine to me.

When you start to think of it this way, you can see that ColdFusion's CFParam tag is really just the template-based equivalent of the CFArgument tag; the CFParam tag is just defining the "arguments" that get submitted to this template for processing. From this point of view, separating out the data TYPE validation from the data VALUE validation, seems almost natural:

  • <cffunction>
  • <!--- Define arguments. --->
  • <cfparam .... />
  •  
  • <!--- Process data. --->
  • </cffunction>

Of course, in a user defined function (UDF), you would use the CFArgument tag instead of the CFParam tag, but I am using CFParam above for the purposes of illustrating flow similarities.

In what might seem like a cheap shot, I almost want to answer the challenge with another question. If you don't think that all of your data TYPE validation should be done by CFParam, that it should be mixed with your other validation rules, then I ask you this, do you use Type validation on your CFArgument tags? I would assume that most of you do. Sure, there are those of you who put "any" in order to gain performance increases, but I would guess that the majority of ColdFusion programmers (who use CFArgument), type their function parameters.

And why do we type our function parameters? Convenience! We want to know that by the time our CFArgument tags have executed we can be sure that all of the values in the ARGUMENTS scope are of a data type that we are expecting. When we expect a String, we want to know that a string was passed in. When we expect a Struct, we want to know that a struct was passed in.

I hope that this clarifies my point a bit. Now, I am just saying that this methodology will make your coding more convenient; I am not saying that it is required. I assume that those of you who do NOT type your function parameters and feel like doing your type validation in the meat of your function bodies will see no need to use CFParam for type validation. But, if you do type your function parameters, then shouldn't you also be doing type validation with your CFParam tags? Why mix the responsibilities in one place when the benefits of concern separation have been so apparent in a functionally equivalent environment for so long?

Thanks Javi for challenging me to get my thoughts in order!




Reader Comments

Excellent post. I totally agree. The only thing I contend could be different about cfparam is that if the type didn't match, you could use the default instead of throw an error.

Especially on search pages, but with other forms as well, I want to validate the type, but set a default if it fails so the rest of the page can process cleanly. Its a good way to handle security and bad links to a template gracefully. Though I would not do the same for functions.

Mike.

Reply to this Comment

@Mike,

It's funny that you mention that because a while back I actually said it would be really cool if CFParam would have a "Catch" attribute which would be like a Default attribute that would catch exceptions:

http://www.bennadel.com/index.cfm?dax=blog:594.view

Of course, it might just be easier to have the Default attribute act as the Catch attribute.

Reply to this Comment

I think in most cases, it would make sense to use the default attribute's value if the type validation failed. Maybe the catch attribute should be a boolean that determines if the programmer wants the exception caught. Maybe a better name for this attribute would be something like failOnError. Here's an example:

<cfparam name="startRow" type="range" min="1" max="#qResult.recordCount#" default="1" failOnError="false">

A lot cleaner than wrapping it with cftry/cfcatch.

Reply to this Comment

Glad to see I'm not the only one.

I always thought of an onError="default|throw|etc." attribute, but in all reality, what would replace the etc.? Good call brad.

And Ben, if only the "CF Nook and Cranny Analysis" award was mine to give. You add a lot to the community with your posts on these things.

Reply to this Comment

Thanks. I'm seriously considering a cf_param tag (as Ben talked about). If Adobe decides to add this feature in CF9, it would be easy to replace the custom tag. I'm just not sure of the performance hit.... hmmm... who cares... I'm doing it!

Reply to this Comment

@Mike,

Thanks for the word of praise. I love looking into this stuff. Always, trying to find a better way to do things or a new way to look at problems.

@Brad,

I am curious about the processing hit. I don't think it can be TOO much as custom tags are all hooked up at compile time, right? So, I don't think there will be much additional overhead to to calling that as opposed to having inline logic.

Reply to this Comment

What about disabling the type checking in CFCs?

Disable CFC Type Check
When checked, UDF arguments of CFC type is not validated. The arguments are treated as type "ANY". Use this setting in a production environment only.

In my opinion, the type checking that CF enforces is a lot more to do with debugging as it will tell you if you accidentally pass a string where it is expecting a numeric. When you work on a production environment you can turn off the type checking for CFCs and help your application go faster. But not if you are using it as part of your validation.

But that also brings up the point that you would probably do the same type checking in your validation if you didn't do it through the argument.

I guess that a lot depends on you you are coding it.

Reply to this Comment

@Randy,

This is very interesting. I didn't even know that this option existed. I can see how type checking on CFargument tags is more about debugging because it assumes that once you have tested your code, the environment is secure. This might be true most of the time when dealing with CFCs; however, dealing with form posts, the same is not true. The fact that this data is coming from the client makes it, by default, not "secure" in terms of dependability.

Interested about the CFC type checking though... mulling that one over in my mind.

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.