Node.js framework comparison: Hapi.js and Sails.js
In an era of web development node.js is most widely used a server-side framework, Node.js is an event-driven I/O framework built on top of V8 JavaScript engine, it allows Javascript to be executed on the server side and uses a wicked fast V8 engine which was developed by Google for the Chrome Browser.
The basic philosophy of node.js is :-
- Non-Blocking I/O — Every I/O call must take a callback which will be executed as soon as response arrives whether it is to retrieve information from disk, network or another process
- Built-in support for most important protocols — HTTP, DNS, TLS
- Low-Level — Do not remove functionality present at POSIX layer.For example, support half-closed TCP connections
- Stream Everything — never force buffering of data
Node.js is different from client-side Javascript in that it removes certain things, like DOM manipulation, and adds support for evented I/O, processes, streams, HTTP, SSL, DNS, string and buffer processing and C/C++ addons
Let’s skip the boring general buzzword bingo introduction and get to the meat of the matter — comparison between two popular Node.js frameworks?
Judging frameworks is highly subjective. When it comes to building enterprise-level applications, we need to consider some of the following things:
- Best practices and patterns: Whether the framework is DIY or provides clear patterns to use.
- Configuration: How easy it is to configure the framework.
- Convention: Is there a convention to follow if that’s the preferred route?
- Horizontal scaling: How easy it is to scale apps built with this framework.
- Testing: How to test the application.
- Scaffolding: How much developers have to code manually vs. using built-in code generators.
- Monitoring: How to monitor the application
- Track record: How proven a framework is, i.e., who supports it and how well it is maintained.
- Integration: How rich the ecosystem of plugins/connectors is.
- ORM/ODM: Is there an object-relational/document mapper.
While performance is important, it varies on the requirements and business logic of a particular project. Running meaningful benchmark tests is non-trivial.
So what’s a tradeoff in using a minimalistic Node.js framework? The tradeoff is an increase in time and harder maintainability because when a team chooses an open-source project, they can leverage other contributors for maintenance. This is not the case when the same team settles on a closed-source in-house system that is supported only by this company.
In the end, you need to think for yourself and make your own decisions. Your target application might focus and/or need different things. This article can only highlight certain facts. And even that is most likely in a subjective manner, as with almost anything written or spoken by a person. 😉
Hapi.js
Hapi (for HTTP API server) is supported by Walmart Labs, so it clearly has a proven track record of serving a lot of traffic in production (#nodebf- Node Black Friday).
Hapi comes with built-in support for input validation, caching, authentication and other features. It does not provide an ORM/ODM right out of the box, but there is an extensive list of third-party plugins.
The power of Hapi is that you get a great amount of control over the request handling. This comes in handy in enterprise applications, because they need to handle a lot of logic.
Other pros include:
- Plugin-based architecture: Pick and choose modules to scale your app
- Caching: Improve performance
- Configuration-centric: Use configuration files
- Rich web server functionality: Speed up your development
- Detailed API documentation: Learn the framework quickly
- Proven track record and support: Get support from community and contributors
- Supports micro-services: Get better separation of business logic and scalability with Seneca and chairo plugin.
Some of the drawbacks of Hapi include:
- Developers need to figure out the code structure on their own
- “Locks” developers into using hapi-specific modules and plugins such as catbox, joi, boom, tv, good, travelogue, and yar; and which are not compatible with Express/Connect
- Endpoints are created manually
- Refactoring is manual
- Endpoints are tested manually
Having no built-in ORM/ODM is not a minus per se as not all enterprise apps need a database. For example, an orchestration layer that pulls data from a legacy SOAP service doesn’t need a MongoDB driver with models and schemas because it is getting data from services and might be caching the data in Redis.
As far as the code goes, Hapi is distinct from the other frameworks in this article, because it wasn’t built on top of Express. This architecture requires additional learning for developers familiar with Express (as the majority of us are) because they can apply their Express.js skills to Hapi.
A simple Hapi server with two routes GET / and GET /name would look like this:
'use strict';const Hapi = require('hapi');// Create a server with a host and portconst server = Hapi.server({ host:'localhost', port:8000 });// Add the routeserver.route({
method:'GET',
path:'/hello',
handler: (request,h) => {
return 'hello world';
}});// Start the serverasync function start() {
try {
await server.start();
} catch (err) {
console.log(err);
process.exit(1);
}console.log('Server running at:', server.info.uri);};start();
To get started simply install Hapi with npm as you would any other dependency:
npm install hapi --save
Social proof for Hapi is at 9,207 GitHub stars and 722,014 npm downloads in the last month as of this writing (March 2018).
Website: http://hapijs.com
GitHub: http://github.com/hapijs/hapi
npm: https://www.npmjs.org/package/hapi
Sails.js
Sails.js was built on top of Express.js; therefore it’s easier to learn for people already familiar with Express.js.
Sails.js has a rich scaffolding. Think Ruby on Rails (hence the name “sails”). This allows developers to create RESTful API endpoint without writing any code. The auto-generated code can be customized later to suit particular business needs.
Sails.js is an MVC framework and it comes with the database ORM/ODM Waterline, which supports various databases.
Sails.js also comes with built-in support for WebSockets with Socket.io and an asset tool (Grunt). However, Sails.js lets you decide on the front-end layer, which is often implemented with Angular.js, Backbone.js or any other front-end framework.
The good insights of Sails.js:
- Provides good code organization and blueprints
- Built-in support for WebSockets
- Supports various databases
- Data validation
- Auto-generated code for controllers, models, and routes
- Many out-of-the-box security features, e.g., CSRF and compatibility with Lusca
- Built-in file upload library
- Good documentation
- Flexible and modular architecture with hooks and plugins
Some cons such as:
- Steep learning curve
- Opinionated
Here’s an example of defining routes in the config/routes.js file of a Sails.js project:
module.exports.routes = {
'get /signup': { view: 'conversion/signup' },
'post /signup': 'AuthController.processSignup',
'get /login': { view: 'portal/login' },
'post /login': 'AuthController.processLogin',
'/logout': 'AuthController.logout',
'get /me': 'UserController.profile'
}
As you see, the abstraction — meaning the logic for the routes is somewhere else — keeps the routes.js file lean and clean. This is important in large enterprise-level applications because it provides control and good code organization.
To get started with Sails.js, install it as a command-line tool with npm and run the generator:
npm -g install sails
Sails.js new sails-test
cd sails-test
Sails.js lift
The resulting skeleton project will have these folders:
/api
: all server-side logic such as controllers, models, policies, responses (request handlers) and services (re-usable components)
/assets
: static assets, such as images, front-end JavaScript, styles, etc.
/config
: configuration settings, such as environments, locales, middleware
/tasks
: Grunt build tasks
/views
: server-side templates
Social proof, Sails.js is at 18,553 GitHub stars and 79,352 npm downloads in the last month as of this writing (March 2018).
Website: http://sailsjs.org
GitHub: https://github.com/balderdashy/sails/
npm: https://www.npmjs.org/package/sails
Verdict
I intentionally left out the default choice for building Node.js/Io.js apps, Express.js, because it would have been too easy to pick on its lack of code generators, organization, and built-in database support. However, you shouldn’t discount Express.js. It might be a better choice for rapid prototyping or highly-customized projects. The number of Express.js/Connect middleware modules is vast. This is the reason why you might want to pick Sails.js. They are compatible with Express.js middleware.
It is definitely heavy-weight in the Node.js-framework space at the moment (March 2018). They bring built-in ORM/ODM and rich scaffolding, which will save hours for developers.
The drawback of Sails.js is obvious. As with any comprehensive frameworks, especially the ones that use convention over configuration and which performs a lot of magic for developers, there’s some amount of learning required.
Hapi stands on its own because its architecture is different from Express.js by design. This allows for more granular control over the request and response life-cycle.
Although I’m including GitHub stars and last month’s npm downloads as a proxy for trends, take the social proof with a grain of salt. It’s not always accurate, because the longer a framework is out there, and the better it’s promoted, the bigger the stats will be. Conversely, the stats for a superior library might be lower just because this module is newer.
I’m not going to advocate for any of the particular frameworks. They are obviously superior to writing and maintaining your own libraries or using bare-bone Express.js in the most cases. My recommendation is to use them based on their pros and cons as it suits your particular project.
Don’t hesitate to clap if you considered this a worthwhile read and follow on medium(Shailesh Shekhawat) for more javascript articles!
Originally published at 101node.io.