Building AVR, Part 2: CFML Architecture

Once AIM was built, we needed a product to display the inventory that had been managed. The AutoConX Vertical (Responsive), or AVR, is a white-label product that allows publishers (newspaper or magazine) list inventory from sellers in their area. It’s a digital classified system that offers a lot of customization and flexibility.

This project was trickier than AIM because AIM was a brand new product. AVR, however, had to be a modern and responsive site that met all the publishers’ expectations from the legacy product. Publishers wouldn’t switch unless they saw real value in the new system. We had to build a product that we would put our own products on.

This is the story of the CFML architecture for AVR.

With AIM, I experimented with my own micro-framework called CoreConX. For AVR, I decided to upgrade to a popular, full-service CFML framework called ColdBox. ColdBox helped me codify the types of components I was writing, and I was gradually able to divide my code into more logical blocks. This improved the readability, flexibility and efficiency of the application.

How is the CFML organized? There’s a handler for each page type, a layout for about the same and parameterized views to build each visual block of UI. ColdBox makes it easy to define and display parameterized views. Their API for calling those views is much nicer than what I had used in AIM, so it was a nice bonus. ColdBox also has interceptors, which allow developers to inject code around various events in the application. This really revolutionized my ability to easily add debugging and logging to the models in the application without writing and rewriting the same boilerplate code.

ColdBox makes it easy to specify additional, external locations for various aspects of the application. This has allowed me to put models, modules and interceptors into a central location and call them from multiple codebases. ColdBox ships with WireBox, a dependency injector that makes it easy to define relationships and abstract away the instantiation code.
All of this stuff was new to me, as I had only ever used my own frameworks or no framework before. My eyes have been opened.

How to handle views? CFML is part tag language and part script language. It was designed to blend in with HTML, so it’s easy to write views. It’s another matter to write views that are reusable and logic-less. ColdBox makes this easy with their view system and view helpers. This increased reusability of my views and also came in handy for the style guide. I could use the same exact view in both places by just passing fake data to the Style Guide. This made it possible to produce a living style guide that changed as actual code changed and allowed me to establish a visual regression testing procedure using PhantomCSS.

What about testing? Testing was a first-class citizen on this project. Every component was built with testing in mind. There is not enough test-shaming in the CFML community, despite there being good tools to test with and absolutely no excuse not to write tests. I created test suites for the models and services and used the BDD-style syntax within TestBox to write them. I typically develop using TestBox’s HTML runner, but the simpler runners came in handy as part of the Gulp test:cfml task and precommit hook.

What did I do wrong? The project still suffers from some slack delineation of concerns. Since I was learning ColdBox as I was developing the application, I failed to take advantage of some really powerful features and settings in the framework. Refactoring is an option (especially thanks to all the testing that’s in place), but it still takes time. As I get better at using ColdBox, the codebase will get better, and the product will get better, too.