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:

<cfcomponent>
<cffunction name="onApplicationStart">
<cfset application.foo = "something">
</cffunction>
</cfcomponent>

Then this:

<cfif not structKeyExists(application, "foo")>
<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.

<cffunction name="onRequest" returnType="void">
<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).

function parseSES() {
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).

<cffunction name="onRequest" returnType="void">
<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.

Comments
That's a pretty cool idea. To take that even one step further, what would be totally sweet is if ColdFusion could handle 404 errors a bit better and then we could use OnRequest() to re-write URLs... very similar to what you are doing, except that your page exists, where as a fake, SEO page might not.
# Posted By Ben Nadel | 5/16/07 10:23 AM
Don't forget that onRequest() breaks web service / Flash Remoting calls to CFCs. See the Application.cfc documentation for more details on why.
# Posted By Sean Corfield | 5/18/07 4:21 AM
Sean is correct, it will break. A long while back, Ray Camden posted a simple solution for this, which was simply to delete the OnRequest() application event if a web service was being called.

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...
# Posted By Ben Nadel | 5/18/07 7:18 AM
Thanks Sean/Ben - I actually did not know that. It makes sense though...

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...
# Posted By todd sharp | 5/18/07 9:27 AM
# Posted By Sean Corfield | 5/18/07 11:20 AM
Ha ha ha ha... sorry, I didn't mean any disrespect by not giving you credit :) Small world.
# Posted By Ben Nadel | 5/18/07 11:22 AM
NP. I just think it's funny that my 'hack' might become a 'standard practice' :)
# Posted By Sean Corfield | 5/18/07 11:46 AM
I think it's quite an elegant solution. And, frankly, I think it's really cool that you can remove application-level events at page run time. Cool!
# Posted By Ben Nadel | 5/18/07 11:48 AM
I wouldn't consider it a 'hack' to have the cfc in a separate directory without an onRequest...
# Posted By todd sharp | 5/18/07 11:57 AM
@Todd, no I wouldn't consider that a hack either. My hack was deleting onRequest from the CFC on the fly inside onRequestStart.
# Posted By Sean Corfield | 5/18/07 12:24 PM
I'm new to using Application.cfc, and I have a question. Is there a difference between putting code in onRequestStart vs. onRequest before the template include? I've put the parseSES() function call in onRequestStart(), and I didn't know if it mattered one way or another.

@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().
# Posted By Rick Hopper | 11/16/07 12:37 PM

Calendar

Sun Mon Tue Wed Thu Fri Sat
  12345
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31   

Subscribe

Enter your email address to subscribe to this blog.

Tags

actionscript ajax blogging cfsnippets coldfusion flash forms flex misc model-glue off topic personal project learn slidesix sql

Recent Comments

More CF+Java: Compiling Classes And Persisting Objects
Getburl said: I have been attempting to get Db4o working in my CF application and I have not succeeded. I would lo... [More]

Thoughts On Ajax Frameworks And ColdFusion/Adobe
Erast said: http://fanniecollins.10gb... emo http://gracetrevino.phree...... [More]

Extending Ext With Ext Extensions
Erast said: http://fanniecollins.10gb... emo http://gracetrevino.phree...... [More]

CF Needs An Open Source Contact List Importer
Kay Smoljak said: Heh, the fact that sites DO it doesn't mean they SHOULD. To us it's ok, but to a non-tech-savvy user... [More]

A Few Project Updates
Helena said: Now punctually what is the situation ? [More]

RSS


coldfusionbloggers

FullAsAGoog MXNA

Consumed By Feed-Squirrel.com