Hands On Sails.js, build Node.js webapps in minutes.

Vincent Teyssier
5 min readOct 20, 2019

Sails.js is a js framework on top of Node.js with which you can deploy an enterprise grade web app in no time. Connectivity to most of modern DBs is supported, API creation is swifter than swift, and you can embed any frontend. It follows the classic Model View Controller model and uses a JSON API.

Before starting, a little disclaimer. Since Sails is based on Node, you have to keep in mind that Node has some serious limitation when it comes to backend processing. Multi-threading is not supported natively, which means that this is not suited for compute intensive calls. A typical example would be long running queries on database. Though calls to backend API are asynchronous, they are running on a single thread. Each call is processed one by one, so if you have a long running process, all other request will be queue while waiting that this process completes.

Installing Sails

Sails being build on top of Node, installation is going through the node package manager. That means you need to have Node pre installed.

npm install sails -g

You probably also want to have the connectors you’d like to use for you database. These have to be installed separately.

In our example let’s use a MySQL adapter:

npm install sails-mysql --save

For a full list of available adapter, please refer to this link: here

Let’s get started

First of all let’s create a new empty project:

sails new myproject

The folder structure and basic files get created automatically.

Open a terminal and simply type:

sails lift

Here you go, your webserver is up and your first page online. Result is visible on your localhost port 1337 by default.

localhost:1337 

If you want to modify that page, simply go to your views folder and edit the ejs file you would like to modify or create new ones.

By default, views are generated from the views/layouts/layout.ejs file.
You will find inside it a <%body%> tag. This is the placeholder which is used to insert the final view which is served to the browser. We’ll get back to that later on.

Create your backend API

In this example we are going to create an api to create/edit users stored in a database. We’ll call it “users”.

sails generate api users

Here you go. Sails generate automatically all that is needed for that API.
If you look at your file structure you’ll find a new UsersController.js in the controller folder and a new Users.js file in the model folder.

Once your API is generated you need to restart the server in order to activate it. Ctrl+C on your terminal then sails lift and here you go.

Go to localhost:1337/users and you’ll get a response (empty though since we have not created anything).

Blueprints

Sails comes with premade constructors and editors for your API. That means that without coding anything you can create or update objects. By default these objects are stored as a filesystem, in the next step we’ll do that through a database.

Available methods are find, findOne, create, update, destroy, populate, add or remove.
You can override the default code if needed but we’ll skip that for this tutorial.

Try the following:

localhost:1337/users/create?firstname=John&lastname=Doe

Here you go, you have your first user in the system. localhost:1337/users will return your newly created user details. An id, a creation date and an update date are attached by default.

Database adapter

We have previously installed the mysql adapter, so let’s declare it in the config file. Edit your config/connections.js and scroll down until you find a commented section related to MySQL. Uncomment the someMysqlServer section and enter your db parameters (host, port, user, password and optionally db, here we’ll call the db usersdb). Sails will take care of the database creation, no need to have pre-created db.

Now let’s edit api/models/Users.js , define your columns in the attributes section and add connection after it:

attributes: {
firstname: {type: 'string'},
lastname: {type: 'string'}
},
connection:’someMysqlServer’

Save and from now Sails will work with your MySQL db, not anymore with the file system. So the user created earlier will not be output when listing users.

We now have a fully functional API connected to our MySQL DB.

Page design

As explained earlier, the layout.ejs is your base page, which means that any external stylesheet, font, scripts, etc… needs to be declared in that page. However be cautious of not adding any code in the <! — STYLES — > section as it would be overwritten on next compilation.

The default HTML that is served through the layout file is coming from the homepage.ejs file. So simply empty it and replace it by whatever HTML you would like to have there.

So keep in mind that core elements served on every page need to be added to the layout file (a navbar for example) while page specific elements need to be added to specific ejs files in the views folder.

Let’s interact with the DB from the frontend

On our homepage, let’s add a simple link which we would use to display the list of users in the DB:

<a href=”/users/displayAll”>Display users</a>

The displayAll method does not exist yet, so let’s create a controller function for it. Edit the /api/controllers/UsersController.js as following:

module.exports = {
displayAll:function(request, response){
Users.find({}).exec(function(err, users){
if(err){res.send(500, 'Query failed');}
response.view('displayAll', {users: users});
});
}
};

What we do here is declaring a method as a function taking a request and a response as parameters, we handle potential errors and if none then we return a view to which we pass our users list.

Now let’s go to the views folder and create a file called displayAll.ejs

Let’s create a HTML table to display our results:

<table>
<thead>
<tr>
<th>ID</td>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
<% users.forEach(function(user){ %>
<tr>
<td> <%= user.id %> </td>
<td> <%= user.firstname %> </td>
<td> <%= user.lastname %> </td>
</tr>
<% }) %>
</tbody>
</table>

The object you passed earlier is used in the <% %> tags. We loop through our result list, and for each user we access it’s attributes

Edit API methods or create custom ones

All default API methods are available in the following location:

/lib/hooks/blueprints/actions/

If you do not wish to edit sails generated code but rather override the function in a custom file, there is a very nice method details in this StackOverflow response: https://stackoverflow.com/a/22274325/2175173

To create custom methods, simply add a new file in the /api/blueprints folder. Let’s call one helloworld.js. To activate this method you need to create a route for it. Edit /config/routes.js and add the related route as follow:

'GET /helloworld': {blueprint: 'helloworld'}

Conclusion

In this article we have explored basic functionalities of Sails.js. What I really like about it is how fast you can prototype. Based around an MVC architecture and JSON API, it offers adapters for most of the existing DBs and generates blueprints API in a matter of seconds.

I think the following statement found on YC summarizes quite well what sails is good at, ie iterating quickly:

“Sails glues things together in a way that is useful for iterating quickly as a newbie, but you can’t build a realtime SaaS on it.”

Simplicity often comes at the expense of flexibility. And when you dig a bit more into Sails you may have needs that go beyond what Sails offers in flexibility.

--

--