Like most of you that came to Ruby on Rails. I was excited to see what this promising framework could do for productivity. Before Rails I had designed large scale commercial web applications on both C++ and Java. My real specialty was to define the framework and then extend it as the application demands. We wanted our code to be DRY (before everyone was using the term DRY). A good framework adds structure, is easy to understand, is easy to extend and eliminates repetitive code. Rails certainly lives up to my definition of a good framework. It handles many of the most common issues that teams building data driven web applications have to solve. Ruby is the giant's shoulders that Rails stands on. The language is so expressive and dynamic it creates so many possibilities.
Now it is time for a small trip down architecture memory lane.
I've been developing data driven web applications since 1996. Looking back on it is seems archaic. At the time we were forging new ground.
Version 1.0 1996: We created one of the earliest commercial, dynamic, configurable, web based business applications. One thing that made these applications so effective is that they were massively configurable by the clients. Everything, and I mean everything, could be customized by the client. Back then the tools were non-existent. Our first application was MSFT based. Good old fashion COM objects talking to ASP 1.0. We developed a model layer with the COM objects and the ASP programmers then consumed them to present the view. It was a simple MV design. (No controller.) HTML was so limited back then, so we had a java applet that handled the advanced data entry UI. This essentially had to mimic what we had built as a windows application.
Version 3.0 1998: So far these applications were installed by large fortune 500 businesses. But it was too complicated to setup and maintain for a midsize company. So we introduced the Software as a Service (SaaS). Back then we called it ASP or our Hosted business. This introduced a whole bunch of new design challenges. Should there be one database per customer or larger databases shared with a 'domain' column partitioning the data. How do you manage it? How do you scale it? How do you secure it. This is before really anyone else had a viable SaaS product much less business model.
Version 3.0 2001: The success of all the earlier projects led to more customers with even more needs. This time they need to have a global solution that could handle many languages simultaneously. Like many code bases the investment into refactoring the original design was borrowed from for years. As a result it never really evolved as it could have. By now the tools had advanced very far. Java (J2EE) was leading the charge with MSFT 'embracing and 'extending' with .Net. We had already switched to Java (J2EE) and built a very cool XML driven B2B product that integrated suppliers in the procurement chain.
So it was time to build the mother of all projects. It had a list of requirements that would scare off most engineers.
We started with a simple J2EE stack layered with a bunch of Apache technologies. We chose Turbine as our MVC. Our model layer was based on Torque. Torque was great for navigating the model, insert, updates, deletes and transactions. But our views were often hitting many tables and a pedestrian Torque implementation would result in too many database round trips. So we introduced our own read only data access layer RDAL (Rapid Data Access Layer). RDAL allowed us to write portable SQL and get very efficient data-access out of the system all while looking like a Torque model object to the view. We considered JSP, ECS and Struts for the view layer. In the end we decided against all of them to selected Velocity. What attracted me to Velocity was the simplicity of the templating language. It could do what you normally need to do in a view very well, loop, conditionals. It was not expressive enough to put logic into the view. We could re-use snippets of code with it (like a Rails partial). Essentially what we had was a J2EE/Apache MVC stack that did much of what you find in Rails.
So now we had an application framework, big deal. We were building database driven web applications. So we have a lot of CRUD operations to deal with. Those CRUD interfaces all had to deal with the following:
· It was a SaaS offering so every CRUD set of views had to be domain aware.
· Most CRUD views had to support custom fields
· Every view had to be multi-lingual with multiple users viewing the site in different languages simultaneously.
· Views had to support role based behavior. (Be aware of the role of the current user and present different options based on their role.)
· It was a SaaS application so it had to be VERY secure. We chose to implement the OWASP security standards for the application.
· Every view could be customized by an consulting engineer. That customization would override the default view behavior on a per-customer basis. The consults should also be able to add new views for that client.
Dang that’s a lot of stuff each developer has to be concerned about. Where to start? The view layer really does nothing to provide any productivity to solve any of these problems. If you want to build a new or edit form you have to write a whole bunch of form html. If you wanted a list you would have to write a bunch of table markup. So the question became how do you DRY up the view and meet the requirements above?
Our answer was to introduce a presentation markup language. You would describe your model in the markup and it would generate a CRUD set of views for you that does all of the above automatically. It was really easy to add new CRUD views on a given model. It was easy to change the UI design for a given element. We had a UI designer that would introduce new behavior as we progressed on the project. We could modify all the views built so far with this new UI behavior. Did I mention that it would generate tests for you as well? It was slick as snot.
The presentation markup was concerned only with how you want to render the model(s). From the markup you could embed velocity code just like a partial. You could call java ‘helper’ methods. It allowed us to have declarative UI for much of the system.
This blog is will follow along as I solve the same problem, extending the rails framework along the way.