An Introduction to Sails.js
Sails.js is a Node.js MVC (model–view–controller) framework that follows the “convention over configuration” principle. It’s inspired by the popular Ruby on Rails web framework, and allows you to quickly build REST APIs, single-page apps and real-time (WebSockets-based) apps. It makes extensive use of code generators that allow you to build your application with less writing of code—particularly of common code that can be otherwise scaffolded.
Sails.js has many great features:
- it’s built on Express.js
- it has real-time support with WebSockets
- it takes a “convention over configuration” approach
- it has powerful code generation, thanks to Blueprints
- it’s database agnostic thanks to its powerful Waterline ORM/ODM
- it supports multiple data stores in the same project
- it has good documentation.
There are currently a few important cons, such as:
- no support for JOIN query in Waterline
- no support for SQL transactions until Sails v1.0 (in beta at the time of writing)
- until version 1.0, it still uses Express.js v3, which is EOL (end of life)
- development is very slow.
Sails.js vs Express.js
Software development is all about building abstractions. Sails.js is a high-level abstraction layer on top of Express.js (which itself is an abstraction over Node’s HTTP modules) that provides routing, middleware, file serving and so on. It also adds a powerful ORM/ODM, the MVC architectural pattern, and a powerful generator CLI (among other features).
You can build web applications using Node’s low-level HTTP service and other utility modules (such as the filesystem module) but it’s not recommended except for the sake of learning the Node.js platform. You can also take a step up and use Express.js, which is a popular, lightweight framework for building web apps.
You’ll have routing and other useful constructs for web apps, but you’ll need to take care of pretty much everything from configuration, file structure and code organization to working with databases.
MongoDB is the preferred database system among Node/Express developers, but you can use any database you want. The most important point here is that Express doesn’t provide any built-in APIs when it comes to databases.
The Waterline ORM/ODM
One key feature of Sails.js is Waterline, a powerful ORM (object relational mapper) for SQL-based databases and ODM (object document mapper) for NoSQL document-based databases. Waterline abstracts away all the complexities when working with databases and, most importantly, with Waterline you don’t have to make the decision of choosing a database system when you’re just starting development. It also doesn’t intimidate you when your client hasn’t yet decided on the database technology to use.
You can start building you application without a single line of configuration. In fact, you don’t have to install a database system at all initially. Thanks to the built-in
sails-disk NeDB-based file database, you can transparently use the file system to store and retrieve data for testing your application functionality.
Once you’re ready and you have decided on the convenient database system you want to use for your project, you can then simply switch the database by installing the relevant adapter for your database system. Waterline has official adapters for popular relational database systems such as MySQL and PostgreSQL and the NoSQL databases, such as MongoDB and Redis, and the community has also built numerous adapters for the other popular database systems such as Oracle, MSSQL, DB2, SQLite, CouchDB and neo4j. In case when you can’t find an adapter for the database system you want to use, you can develop your own custom adapter.
Waterline abstracts away the differences between different database systems and allows you to have a normalized interface for your application to communicate with any supported database system. You don’t have to work with SQL or any low-level API (for NoSQL databases) but that doesn’t mean you can’t (at least for SQL-based databases and MongoDB).
There are situations when you need to write custom SQL, for example, for performance reasons, for working with complex database requirements, or for accessing database-specific features. In this case, you can use the
.query() method available only on the Waterline models that are configured to use SQL systems (you can find more information about
query() from the docs).
Since different database systems have common and database-specific features, the Waterline ORM/ODM can only be good for you as long as you only constrain yourself to use the common features. Also, if you use raw SQL or native MongoDB APIs, you’ll lose many of the features of Waterline, including the ability to switch between different databases.
Getting Started with Sails.js
Now that we’ve covered the basic concepts and features of Sails.js, let’s see how you can quickly get started using Sails.js to create new projects and lift them.
Before you can use Sails.js, you need to have a development environment with Node.js (and npm) installed. You can install both of them by heading to the official Node.js website and downloading the right installer for your operating system.
Make sure, also, to install whatever database management system you want to use with Sails.js (either a relational or a NoSQL database). If you’re not interested by using a full-fledged database system, at this point, you can still work with Sails.js thanks to
sails-disk, which allows you to have a file-based database out of the box.
Installing the Sails.js CLI
After satisfying the working development requirements, you can head over to your terminal (Linux and macOS) or command prompt (Windows) and install the Sails.js Command Line Utility, globally, from npm:
sudo npm install sails -g
If you want to install the latest 1.0 version to try the new features, you need to use the beta version:
npm install sails@beta -g
You may or may not need sudo to install packages globally depending on your npm configuration.
Scaffolding a Sails.js Project
After installing the Sails.js CLI, you can go ahead and scaffold a new project with one command:
sails new sailsdemo
This will create a new folder for your project named
sailsdemo on your current directory. You can also scaffold your project files inside an existing folder with this:
sails new .
You can scaffold a new Sails.js project without a front end with this:
sails new sailsdemo --no-frontend
Find more information about the features of the CLI from the docs.
The Anatomy of a Sails.js Project
Here’s a screenshot of a project generated using the Sails.js CLI:
A Sails.js project is a Node.js module with a
package.json and a
node_modules folder. You may also notice the presence of
Gruntfile.js. Sails.js uses Grunt as a build tool for building front-end assets.
If you’re building an app for the browser, you’re in luck. Sails ships with Grunt — which means your entire front-end asset workflow is completely customizable, and comes with support for all of the great Grunt modules which are already out there. That includes support for Less, Sass, Stylus, CoffeeScript, JST, Jade, Handlebars, Dust, and many more. When you’re ready to go into production, your assets are minified and gzipped automatically. You can even compile your static assets and push them out to a CDN like CloudFront to make your app load even faster. (You can read more about these points on the Sails.js website.)
For more community generators, see this documentation page on the Sails.js site.
The project contains many configuration files and folders. Most of them are self explanatory, but let’s go over the ones you’ll be working with most of the time:
api/controllers: this is the folder where controllers live. Controllers correspond to the C part in MVC. It’s where the business logic for your application exists.
api/models: the folder where models exist. Models correspond to the M part of MVC architecture. This is where you need to put classes or objects that map to your SQL/NoSQL data.
api/policies: this is the folder where you need to put policies for your application
api/responses: this folder contains server response logic such as functions to handle the 404 and 500 responses, etc.
api/services: this where your app-wide services live. A service is a global class encapsulating common logic that can be used throughout many controllers.
./views: this folder contains templates used for displaying views. By default, this folder contains the ejs engine templates, but you can configure any Express-supported engine such as EJS, Jade, Handlebars, Mustache and Underscore etc.
./config: this folder contains many configuration files that enable you to configure every detail of your application, such as CORS, CSRF protection, i18n, http, settings for models, views, logging and policies etc. One important file that you’ll frequently use is
config/routes.js, where you can create your application routes and map them to actual actions in the controllers or to views directly.
Continue reading %An Introduction to Sails.js%