Sails ORM/ODM

Sails has grand goals. It's a smartly built and underappreciated framework that pulls together some of the best utilities available to the node.js community and combines them into one super framework of awesome.

....except that it doesn't....

My main gripe comes from the explanation of ORM/ODM where it claims:

Sails comes installed with a powerful ORM/ODM called Waterline, a datastore-agnostic tool that dramatically simplifies interaction with one or more databases. It provides an abstraction layer on top of the underlying database, allowing you to easily query and manipulate your data without writing vendor-specific integration code.

and goes on to explain some amazing features

  • Database Agnosticism - waterline floats above any database and lets you connect to all of them with a uniform syntax.
  • Compatibility - waterline works with existing databases; you can build models that leverage other data stores used by other business applications without needing to migrate data into whatever storage is used by your sails application.
  • Performance - it is implied that waterline uses databases the way they're intended so as to optimize performance.

Sounds incredible! But while waterline does good work on the ORM side, it falls flat on the ODM site since it doesn't support nested documents.... which basically means it doesn't support document objects; waterline models data in mongo the same way it does in a relational database. That makes waterline's claims of compatibility and performance laughable when considering a document object database.

Here's a tangible example:

//What you might expect a document object of a user to look like
//when stored in a NoSQL database.
var user = {
  name: {
    first: 'Joe'
    last : 'Smith'
  },
  login: {
    name: 'joe.smith',
    auth: 'encrypted'
  }
}

//But ODM in waterline doesn't support nested documents, so
//the object above would need to be flattened out.
var user = {
  firstName: 'Joe',
  lastName : 'Smith',
  loginName: 'joe.smith',
  loginAuth: 'encrypted'
}

It might not seem like a big deal when reviewing a trivial example, but especially when considering an existing NoSQL collection, waterline's inability to represent nested documents within a document object greatly impedes compatibility and performance.

It is worth noting that waterline will allow deep document object models and retrieve data as expected; it only begins to fail when attempting to validate values during CREATE or UPDATE actions. I guess this means waterline doesn't validate during READ, but haven't attempted to confirm.

There is a light at the end of the tunnel! In sails-mongo, a comment on Issue #44 talks about some of the problems, solutions, and plans for enabling embedded documents. It all points to the roadmap of waterline2 which is slated for early-mid 2015. Disappointingly, though, commits to waterline2 have gotten stale.