Timi Ajiboye

Intro to Sails.js

Hi!

This is meant to be a quick and dirty overview of what Sails.js is. Sails.js is a Node.js framework designed to follow the MVC pattern with a "convention over configuration" paradigm to ease the web development process.

What all that simply means is that, a group of people wrote a lot of JavaScript code that you can start from as a base to easily make web applications and APIs.
hellosails.com is focused on creating APIs, so we're not gonna be doing any front-end development.
This means we'll have only Models & Controllers (and no Views).

To get a sense of how Sails.js works, we're gonna create a new application and go over some of the generated files and folders.
If you don't have Sails.js installed:

sudo npm install sails -g

(Make sure you have Node and npm installed prior).

Now, we create a new Sails.js API only application. With no front-end.

sails new testapp --no-frontend

The image below shows the generated file/folder structure you are presented with.

We are going to look at a some of the important folders and files that all come together to form a Sails application.

/api/controllers

The controllers folder houses all your application's controllers. For the sake of those just starting their MVC journey, a controller "represents the objects connecting the model and the view, and is used to communicate between objects in the model and view"*. In our case, the "view" refers to whatever client is consuming whatever API we're making.

To create a controller in Sails,

sails generate controller controller_name [action names separated by spaces...]

An action is simply a function within a sails controller that corresponds to an API endpoint.
For example, you might want to have an endpoint that returns a list of tasks. There has to to be an action in your TasksController that does this for you.

/**
 * TasksController
 *
 * @description :: Server-side logic for managing tasks
 */

module.exports = {

  findAll: function (req, res) {
    // function that does the magic of returning the list of all tasks
  }
    ...
};

Tying a controller action to a URL/endpoint is done by routing. More on that later.

/api/models

The models folder is where all models are kept. If you're new to MVC, a model "represents the underlying, logical structure of data in a software application and the high-level class associated with it. This object model does not contain any information about the user interface."*

To create a model in Sails,

sails generate model user [attribute1:type1, attribute2:type2 ... ]

An example of a user model,

/**
 * User.js
 *
 * @description :: Our user model
 */


module.exports = {
 attributes: {
    email: {
      type: 'email'
    },

    bloodGroup: {
      type: 'string',
      enum: ['A','B','AB','O']
    },

    password: {
      type: 'string'
    }
  }
}; 

You can read about validating model attributes in this other post

/api/services

This folder is where services are found. Services are JavaScript objects with functions that are accessible app-wide; in controllers, models, policies.

/api/policies

In this directory, we have our policies. Policies are rules we create and apply to our controllers for authorization or access control. For example, a default policy that is automatically generated in any new Sails.js application is sessionAuth. This policy will return true (i.e. proceed to the next policy) only if the user is currently authenticated.

module.exports = function(req, res, next) {

  // User is allowed, proceed to the next policy, 
  // or if this is the last policy, the controller
  if (req.session.authenticated) {
    return next();
  }

  // User is not allowed
  // (default res.forbidden() behavior can be overridden in `config/403.js`)
  return res.forbidden('You are not permitted to perform this action.');
};

We can create policies like this to be used by different controllers across our application.

Although the policies themselves are defined in the /api/policies directory, they are applied to the controllers in the /config/policies.js file. In this file, we specify the controller and methods we want to apply the policy to. For example, we may want to apply the sessionAuth policy to a createTask() method in a TasksController controller.

{
  TasksController: {
    createTask: ['sessionAuth']
  }
}

 

/config/routes.js

The routes.js file in the /config/ directory is where we define our application routes. Each route is made up of two parts -

  1. Address - The URL path, and optionally HTTP method, to match. e.g. '/dashboard' or 'post /login'

  2. Target - What should be resolved. This can be specified in a number of ways, e.g. passing an object with a view. However, since we are only working with an API, we can simply pass a controller and function as the target.

module.exports.routes = {
  'post /signup': 'AuthController.processSignup',
  'post /login': 'AuthController.processLogin',
  '/logout': 'AuthController.logout',
  'get /me': 'UserController.profile'
}

 

/config/*

This directory is where all our configuration files live. There are 16 files created for you when you create a new Sails.js project.

Going through each of these files is beyond the scope of this "quick and dirty" introduction. I will go through the most important of these files, e.g. blueprints.js, in their own articles.

*Definitions culled from whatis.com