Are You Using onRequest in Application.cfc?
I'm a really big fan of application.cfc. I like the organization and the fact that I can define certain events and variables based on the various events that happen when my application is used.
To me it's much cleaner and organized to to do this:
<cffunction name="onApplicationStart">
<cfset application.foo = "something">
</cffunction>
</cfcomponent>
Then this:
<cfset application.foo = "something">
</cfif>
Just knowing that foo will only be set if my application starts and that I don't have to worry about whether or not it may already exist makes me happy.
That being said I realized recently that I personally have not been taking full advantage of much of the power of the various functions available. For example, I often take advantage of onRequestStart to do user authentication, page logging, etc - but I rarely use onRequest. So what is a good use case for onRequest? Well lets start with a simple skeleton function showing the structure of onRequest. This is copied from Ray Camden's Application.cfc reference which I highly recommend you get a copy of and use as a skeleton for your applications that use application.cfc.
<cfargument name="thePage" type="string" required="true">
<cfinclude template="#arguments.thePage#">
</cffunction>
Pretty simple eh? The function accepts one argument - the page being requested. So what else can you do in onRequest? Well notice that the page that is passed is then included back into the function. How about doing something before that request? Like what? Well setting variables is a possibility - but may be unlikely. Application wide variables should be set in onApplicationStart. Variables specific to a template would be better off being set in the template itself to avoid confusion and hard to read code. What we could do is repetitive tasks that we'd rather not even care about seeing happen on an individual template basis. Like what? Well lately I've been using onRequest to parse search engine safe (SES) URL's. I will normally have a component of utils/udf's that I create in the application scope. One of the functions may be something like this parseSES function (borrowed once again from Ray).
var pathInfo = reReplaceNoCase(trim(cgi.path_info), '.+\.cfm/? *', '');
var i = 1;
var lastKey = "";
var value = "";
if(not len(pathInfo)) return;
for(i=1; i lte listLen(pathInfo, "/"); i=i+1) {
value = listGetAt(pathInfo, i, "/");
if(i mod 2 is 0) url[lastKey] = value;
else lastKey = value;
}
//did we end with a "dangler?" if((i-1) mod 2 is 1) url[lastKey] = "";
return;
}
So my onRequest would look something like this (assuming the function above was included in a component created in the application scope called utils).
<cfargument name="thePage" type="string" required="true">
<cfset application.utils.parseSES()>
<cfinclude template="#arguments.thePage#">
</cffunction>
Simple but effective. Now I do not have to worry about calling that function on every template. It's just done. I can now assume that every template will correctly interpret a URL like http://foooooo.com/todd/sharp as url.todd = 'sharp'. You could also take advantage of onRequest to cfinclude a UDF library, etc.



I tried to find Ray's original post but I cannot. At the very least, here is a link to a small entry on how I applied Ray's suggestions:
http://www.bennadel.com/blog/430-My-First-ColdFusi...
Typically my CFCs are in a seperate directory with it's own app.cfc that is usually pretty bare bones. I may also have a app.cfc that extends the base app.cfc and overrides potential permissions set in onRequestStart() (Sean I think you actually are the one that turned me on to that) but I don't really see the need to ever consider onRequest in those.
I suppose that brings up a good point though - if you are extending a base app.cfc and it uses onRequest you'll potentially have a problem...
http://ray.camdenfamily.com/index.cfm/2005/10/16/A...
and the solution he quotes is mine:
http://corfield.org/entry/Applicationcfc__onReques...
@Todd. Also, your example for parseSES() was http://foooooo.com/todd/sharp. Does that work without including the filename? When I try that, I get a 404 error, b/c it assumes /todd/sharp is part of the directory path. I was assuming I'd have to work with 404 error handling to be able to leave off the filename, but I wasn't sure if there was a trick to getting it to work with parseSES().