It can be tempting to take shortcuts when configuring routes for your ColdBox app. One pattern I have seen is to create a generic route namespace, with an optional action, that points to a handler, without specifying specific actions like this:
route( "blog/:?action" ).toHandler( "blog" );
The above route takes any URL pattern starting with “/blog/” and lets the Blog.cfc handler deal with the request. If the URL contains a matching handler method, the request calls the action. If the action method is missing from the handler, it triggers the event configured in coldbox.invalidEventHandler
setting (usually your 404 event).
One thing that might be easy to overlook are the global helper UDFs which are automatically injected into handlers, layouts, views, and interceptors. These injected UDFs are also known as “Mixins” and they might come from your own code or 3rd party modules you have installed.
If you try to access a URL with an action that matches the name of a UDF method, you will get an exception error and it won’t trigger the event in your coldbox.invalidEventHandler
setting.
Even if you make the global helper method private, ColdBox will still try to call it and throw the exception.
An Example Using CBAuth:
One of the most popular Coldbox Mixins is from the legendary CBAuth module. CBAuth automatically adds the method auth()
to all handlers. This behavior is extremely convenient, but if you have your route set up like I have done at the top of this post, it will trigger a coldfusion.runtime.TemplateProxy
exception error if you try and visit the URL: /blog/auth/
Any other URL combination that doesn’t match a global UDF, will trigger the configured coldbox.invalidEventHandler
event.
How do you fix this? The best way I can think of is to make sure to be as explicit with your route definitions as possible – even if it means being extra verbose.
// More verbose, but better routing pattern
route( "blog/:id-numeric" ).to( "blog.show" ); // Show a blog post
route( "blog/:anything" ).to( "errors.onMissingPage" ); // catch-all 404
route( "blog/" ).to( "blog.index" ); // list blog posts
route( "pages/:slug/:anything" ).to( "errors.onMissingPage" ); // catch-all 404
route( "pages/:slug" ).to( "pages.show" ); // show a page
route( "pages/" ).to( "pages.index" ); // list pages
Also, ColdBox can automatically create routes for you using “resourceful” route patterns. See more about that here: Resourceful Routes | ColdBox HMVC Documentation
If anyone has any other routing tips, please feel free to include them below.