Scala vs. Node.js as a RESTful backend server
My goto server for a while has been Node.js for a great many reasons including the easy sharing of code and modules across the server and UI with Webpack or Browserify, first class asynchronous support, consistent language environment, and NPM, one of the best package/dependency managers, in my opinion, that exists.
Last year, however, a coworker encouraged me to give Scala a try, and so down the rabbit hole I went. I’ve come out with a somewhat mixed opinion but we’ll get to that. Let me first go through the positives of the experience. While Java is a perfectly practical language, and it has a long history of solid mission critical usage, once you begin to dabble in other languages and language features, Java syntax begins to pale in comparison. Java 8 and 9 will begin to address some of those syntactical shortcomings, and there are alternatives like Jython, Jruby, Groovy, Ceylon, but one of the more prominent JVM languages in the industry has been Scala.
Enough praise of Scala though, let’s get to the differences in the experience of writing a backend in Scala vs. Node.js. Do remember this is a comparison between the development experience between a backend in Scala and Node.js, I am not considering other languages in the comparison, other languages which may have other various pros and cons.
- for/yield – Once you get accustomed to for and yield in Scala, you wonder how you lived without it. Node.js gives you the EventEmitter and promises, and while those do clean things up considerably, they can’t touch the power and conciseness of for and yield in Scala.
- Concurrency – Scala provides access to Akka which opens a whole new world of opportunities for the backend. Also being on the JVM provides a great deal more APIs for creating and handling threads and processes. Not something you would typically do directly in many webapp backends but there if you need it.
- JDK Interoperability – While Scala can’t necessarily compete with Node.js with NPM or the number of active repositories on github, Scala does have access to any java library, and that is a major point. Want to use commons-lang, go ahead, or jOOQ, why not. This is a very compelling reason as there are certain libraries that are simply better in Java. Think the Salesforce API for example, or any RESTful API where you can generated a typed API access layer through a WSDL.
- Asynchronous Libraries – Nearly every database or io library you need is asynchronous out of the box, or can be made so with promisification. This is the case because of the nature of Node.js. The landscape isn’t so well defined with Scala. Given certain backends in Scala can be written with a thread per request model then it is fine for an API call to block, that means not every database API library is asynchronous. Some of them are forked to be asynchronous and labeled as experimental. While they may work fine, the point being you aren’t as nearly guaranteed to have an asynchronous library when you find the functionality you need. When if you do find a forked async library, it may be labeled experimental. In my experience I never ultimately had a particular issue finding what I needed in Scala in terms of async libraries, but the availability isn’t so well defined.
You’ll notice in the above list that my reasons for liking Scala are primarily language specific, and my reasons for liking Node.js are primarily practical in nature. I believe this is a very important difference. While the Scala syntax can be cryptic and infuriating at times, I want to love it, there is a beauty in the syntax and language constructs Scala provides (After you accept the gray hairs). And I believe it is those constructs, combined with the strongly typed system, that attracts me to Scala as a backend, and makes Scala a very compelling alternative to the Node.js backend world. Like any language, you can likely use either language cover the gamut of possible apps you want to create, there will be little you can’t do in either language (save more complicated concurrency), so part of the consideration then becomes experience, feel, and stylistic approach these languages use and how they feel to you as you develop in them.