Move Over LAMP, Make Way for JAMM
After working heads-down with Meteor and MongoDB for four months, I haven’t run into any show-stopping snags.
But adjusting to these new tools can be disorienting, and I find myself comparing and contrasting JAMM to things with which I am more familiar. Over the past decade, I’ve been working on rule-based systems that conform to three-tier architecture.
With this architecture, the client tier, typically a web page or hand held device, communicates with an application server that comprises the middle tier. The middle tier contains business rules that operate on a domain model (i.e., object instances that contain enterprise data). In most cases, the domain model is mapped to a database, and in the Java world, often using Hibernate, the leading object-relational mapping system.
In the three-tier approach, the database tier is frequently seen as nothing more than a storage system, but admittedly in many cases, firms fudge by coding some business logic in database-resident stored procedures and triggers that can technically be characterized as rules. People will argue about the merits of this, but I’ve honestly become fatigued by the controversy; it is mostly religion.
With three-tier architecture, the middle tier is king. The middle tier encapsulates a centrally-controlled domain model that is in a consistent, canonical form (i.e., objects). In theory, by centralizing business rules in the middle tier, cost can be reduced, and software quality can be improved.
Irrespective of whether potential benefits are realized, three-tier architecture is pervasive. A consensus about the viability of this architecture emerged in the early 1990’s and it has remained largely unchallenged to this day.
Tangible cost benefits of three-tier architecture can be difficult to achieve due to complexity. Object-relational mapping is not straightforward due to a set of technical problems collectively referred to as impedance mismatch. It has taken many years of focused effort for Hibernate to be regarded as production-ready. Even now, performance considerations make it likely that caching systems will be necessary, effectively carrying an object-oriented copy of frequently-referenced data in the middle tier.
It takes extraordinary effort to maintain the illusion that our data is represented as neutral objects when in fact the underlying data is stored in relational form. The cost of dealing with this complexity is real, including the difficulty of recruiting developers that have mastered object/relational technologies, but also in operations and technical support, where problems can be difficult to diagnose and correct. Much of this complexity and cost can be reduced by JAMM.
MongoDB as Object Authority
MongoDB stores and maintains data in a form that is functionally equivalent to a traditional middle-tier domain model. Because of this, there is no need to maintain a extra object-oriented copy of the data in the middle tier; instead, middle-tier rules operate upon objects in the database tier, which becomes the central authority for persistent and non-persistent facts. With this approach, the middle tier can be characterized as stateless.
To an engineer familiar with traditional three-tier architecture, this shift in design can trigger alarms. I explored my own feelings about this, and found that they boiled down to visceral concerns about database performance.
To counter these concerns, it is important to understand that accessing data in MongoDB is much faster than an object/relational system. Given a Mongo ID of a document (tantamount to primary key), data can be accessed rapidly because:
- In many cases, the data to be accessed will already be memory
- The data may be indexed in extraordinary ways, including indexing every single field of a given record
- The database tier and middle tiers may in fact be in the same machine, reducing communications overhead
- There is no mapping overhead because the data is stored in object form
Rules in the middle tier can access just the data they need using granular MongoDB selectors (akin to database SELECT statements), and make state changes to MongoDB without carrying an object-oriented copy of the data.
With this approach MongoDB can be viewed as the state authority for both persistent and non-persistent data, supplanting the middle tier. I stress non-persistent, because MongoDB is so fast and convenient, it can be used to handle non-persistent data that would traditionally be kept only in the middle tier.
In short, we need to resist the tendency to look at MongoDB as just a storage system. It can be elevated to a higher plane to become the state authority, the keeper of canonical objects.
Rules on Client Tier
- Data validation without requiring a server round trip
- Data validation via calls to external systems without involving the middle tier (e.g., Google Places API)
- Conditional forms (i.e., certain parts of a web page being displayed or hidden based on answers to questions)
Look forward to more applications pushing rules out to the client tier, and using middle tier services more sparingly for heavy number-crunching or for financial transactions where security is a concern.