Monday, May 24, 2010

Breaking All the Rules

Finally, after 20 years of being raised on the bread and butter of data persistence, I have a project where the client is open to using a non-SQL database. Of course that client is myself, but that alone wouldn't be fair justification for using a non-relational database.
So what are my primary motivations for using a document persistence mechanism on my project?
  • A database that can evolve quickly
  • Database that scales horizontally
  • Accessible via JavaScript
A database that can evolve quickly
Most of the discussion about an evolving database relates to this concept of schema-less databases. While this is the same marketing blurb regurgitated by most of the so called "no-sql" vendors, most applications care that the data which is shoved into persistence conforms to an expected format. My application is no different, and all of the state representation supported by my application is validated against a JSON schema. After all, a schema is almost always necessary if the data you are storing needs to be queried by a field other than ID, or rendered to the screen.
Database that scales horizontally
Who wouldn't enjoy the ability of doubling their transaction count by only doubling the number of database servers? Only time will tell whether the scalability is linear or otherwise, but I am helping to develop a community site that could experience explosive growth if it is successful. So my ideal database would allow a simple mechanism for clustering instances, including a client-side connection that supports failover.
Accessible via JavaScript
This is a strange requirement for many developers right now. When I write it now, I suspect that most developers wonder whether I plan on making database calls directly from the client. While this is very feasible, it is not the case. Instead, I have chosen JavaScript as the language in which our server tier is developed.
Server Side JavaScript (SSJS)
While JavaScript on the server side sounds radical, I am finding it superior to many other approaches I have taken in the past. Perhaps because I have spent most of my career as a Java enterprise developer, I have a particular comfort and trust in the JVM. I have seen it perform faster and faster every year with more and more new languages developed to run upon it.
While I find Java a bit verbose, I like the syntax of Groovy much, much more. After all, Groovy is all Java plus many meta programming tricks and syntactic sugar to make development actually fun again. Over the past several years, I have also programmed in ActionScript, JavaScript, JRuby and read through some examples of Scala, Clojure and Jython.
Eventually, the time came to decide which JVM language to pick as my server side development language. At this point it should come as a surprise that I chose JavaScript. The main reasons for this choice are:
  • Low barrier of entry. Most of our existing development staff knows how to read and write JavaScript. Rhino isn't your grandma's JavaScript either. Support for JavaScript 1.8 is in there and you might scratch your head the first time you see var [a,b] = carArray; as I did.
  • Contractor accessibility. My company frequently augments our staff with contract developers when project load demands it. Instead of now looking for 5 Groovy resources, I am seeking 5 developers with JavaScript experience. It is much easier (and frankly, less expensive) for me to locate and onboard these resources.
  • SSJS movement. My first exposure to server-side JavaScript was Jaxer from Aptana. It had some cool features, but in the end it seemed like ASP code using JavaScript as the server-side language. Since that time, a new movement has begun. The SSJS movement now has a JSGI specification (based on the oldest web server interface - CGI) which acts as a thin layer between a web server and JavaScript controller code. There aren't a lot of production ready MVC frameworks built on this spec yet, but rest assured they are coming.
After using Narwhal/Jack and Persevere and others, I chose RingoJS as our JSGI implementation. I am very happy with it thus far. I like the fact that RIngoJS supports a middleware stack and can be packaged in a standard Java WAR file for deployment.
The fact that RingoJS runs on Rhino was a primary consideration. This means that we have a direct bridge to the ecosystem of Java libraries and frameworks from within JavaScript. We are already using Mongo's Java database driver with a thin JavaScript layer on top to perform persistence. I'm very happy with our choices so far.