While we're approaching the 1.0 release of Meteor, the need and interest in additional databases support (other than MongoDB) has risen consequently. Thus, SQL support is the second most requested feature on the official meteor roadmap (after server-side rendering) and there have been various demands on the forums about supporting Redis (also on the roadmap), RethinkDB, LevelDB, Neo4J, ElasticSearch, Mysql/MariaDB, PosgreSQL, SQLite and some other. More importantly the Meteor community has started to work on atmosphere packages that bring support for these databases and it appeared to be a very difficult task – most projects were abandoned.
What makes the integration of a new database a lot harder in Meteor than in most other web frameworks (including “full stack” JavaScript frameworks like Derby or Sails) lies in the third principle of Meteor:
Database Everywhere. Use the same transparent API to access your database from the client or the server.
This principle is reflected by the usage of minimongo
– an in-memory MongoDB emulator – on the client side of Meteor applications. We all agree it's an amazing feature, making things like latency compensation breeze.
However in the current state of the Meteor platform, this also have a serious consequence for third-party database integrators. Basically they have to emulate the database in a mini{redis|sqlite|...}
package. So if I want to bring sqlite support for Meteor, I first need to write a (reactive) in-memory Javascript port of sqlite that works in a browser (IE8+), which may not be the most straightforward task I can think of.
The other solution to implement a sqlite database could be to keep using minimongo
on the client – because after all we'll end up writing something that will do more or less the same thing, just with a different public API – and then use the npm/nodejs driver on the server. The problem is that it violates the third principle of Meteor, and thus if we want to have latency compensation for our queries (we do), we'll have to write two versions of them: one using minimongo on the client, and one for “real” sqlite on the server, making this solution far less desirable.
So here we are with one of the best platform for building real-time distributed applications, and we can't use anything but MongoDB.
The idea is quite simple, because we want to use the same API on multiple platforms but we don't want to re-implement a JavaScript database for every database we use, we need to:
- Define a generic enough API to handle most features databases offer (key/value stores, schemas, relations, indexes, etc.);
- Define a way to create adapters, ie an interface between this generic API and the database API for a given platform (currently browser, nodejs, or cordova).
Fortunately enough these are the classical roles ORMs stand for, and so we don't need to reinvent the wheel. We already have plenty of experience about APIs that work and how to connect them to database drivers.
So could we just pick one and move on? Not really. Because of the very nature of Meteor applications, a Meteor ORM would need to have the following characteristics:
- Be written in JavaScript, and working in the browser environment
- Allow synchronous calls on the server
- Allow reactivity
- Allow leader/follower architectures and ensure security (never trust the client)
And as far as I'm aware of, there is no JavaScript ORM with all that features. So after all, we may end up needing to create yet another ORM – a MeteORM.
I'm not an expert but I've found a project called Waterline that could be a very good basis for our MeteORM. It's written is JavaScript, used by SailJS (a real-time nodejs framework), has an adaptors architecture, a reasonable query language (similar to what we use today). It also supports models, models validation, and models relations.
I encourage you to take a look at the Waterline documentation. Assuming we choose it as a basis for our ORM, here is what we'll have to figure out:
- How to remove the
.run(callback)
call (I guess we should use.fetch()
instead + use fibers on the server) - How adapters export their data in publications (using the low level DDP API) and how a (potentially different) database gets populated from the DDP flow.
- How to implement client side reactivity on cursors (using
Tracker
)
Once we have this additional layer between the developer and the database, with a generic API and a way to connect new database engines, like what we have today for “plugins” (CSS/JS pre-processors), I'm pretty confident the Meteor community will create an abundance of adapters for all the databases we use and love.
$ meteor add rethinkdb
downloading rethinkdb...
done!
Hi. Going to have to dissent, and speak on behalf of not having an ORM in the core system.
Now, a lot of people have come to Meteor with the view that it's the shiniest, newest NoSQL goodness. And that a single-language document-oriented database is some sort of radical NoSQL alternative to traditional LAMP stacks.
However, others of us have come to Meteor and volunteered countless hours over the past 2 years with the view that it's the 21st century version of MUMPS: a 40 year old single-language document-oriented database technology that powers healthcare EMR systems like VistA and Epic. Disclaimer: I spent nearly a decade as an Oracle Administrator and MUMPS Administrator in the healthcare industry.
So, when I chime in and say that adding an ORMs into the core Meteor infrastructure would be a bad move, I say so from my professional experience having been an administrator for single-language document-oriented database applications. We ran these database apps in mission-critical environments, where people's lives depended on the systems being up-and-running. So, I'm not being critical of this proposal as a hobbyist. But as a professional who's worked with these systems in hospital environments where people's lives depended on their uptime and performance.
For what it's worth, VistA and Epic, which combined account for nearly 35% of all medical records in the US, have been running for 40+ years without an internal ORM. And when compared to Cerner, an Oracle SQL based solution, the difference was night-and-day. The real-world impact is that having an ORM around completely fouls up DevOps, maintenance, and the feature development cycle once an app is in production. ORMs are so bad that people write about them as the Vietnam of Computer Science.
Object Relational Mapping is the Vietnam of Computer Science
The Vietnam of Computer Science
ORMs are like a rubix cube. Great in theory. Illustrates awesome math concepts. Elegant. Everybody has one (lowest common denominator). But why the hell would anybody ever build their mission critical database like a rubix cube? Oh great! We have approximately 5 minutes to pull records and figure out if this person needs blood-thinners before surgery. Quick! Here's a rubix cube! Solve it or somebody bleeds out!
No fracking way.
EMR/PHR systems are such huge clusterfsks because time-and-time again designers keep applying junior level patterns they learned in school, because 'SQL is a best practice'. But VistA and Epic are hold outs, exactly because they were designed in response to real-world needs, before SQL came into fashion. And their data structures actually make sense. Of course, the M language syntax is a complete mess, what with it's method abbreviations, which is why a new language like Javascript is needed. But as far as applications go, MUMPS/VistA/Epic get the data structures right with a document-oriented approach. And an internal ORM would completely foul up the Meteor data model. People may not appreciate it, but Meteor's lack of an ORM is a godsend for development, devops, and operations.
But that's not to say that I don't appreciate why people want an ORM. Data-mapping is a huge issue. And there's a real need to interface with external SQL systems. In my professional opinion, with a decade of database administration experience, the appropriate place for an ORM in the Meteor ecosystem is external to the live-data packages. Something like this:
Anyhow, I bring this up, because there's something of a healthcare working group in the Meteor community. I personally know between one and two dozen developers actively working on healthcare apps with Meteor. And to the extent that I've been coordinating that working group, I'm going to speak up for it and other healthcare professionals using Meteor, and say, 'This ORM suggestion is a really bad idea.' If this moves forward, there would be people interested in forking Meteor at v1.0, and heading it in another direction before having an ORM mess up the internal data model. Bringing an ORM into core Meteor is something of a dealbreaker for some people in the Meteor community.