Intro to Sails.js Framework for Next-Level Nodejs Backend Apps

List Of Content

ADS Area (CARBON)

ADS Area (CARBON)

 

Getting Started

Sails.js is a Backend MVC Framework built on top of Express that provides a Rich set of features that allows you to develop high-level application including servers and full web applications by giving you all the tools you need to start putting your app together without thinking about low-level configuration and setup.

Sails does a lot of things for you out of the box for you and your application.

  • Awesome Sails-CLI that assist you thought out the development process 
  • Security Standard already being handled and taken care of avoiding the highest risks.
  • Models and support for multi-database system plus it includes an ORM for writing once and supporting multiple databases with one single code-base.
  • Node-Machine system supported for Controllers to make it easier for you to develop and maintain your servers and APIs.

If you still can quietly decide why you should choose sails over you basic express app setup you can take a look on the Sails.js website for seeing all the available features and options plus what can Sails do for you.

Now let's install sails and try to Setup and create our first Sails App.

npm install sails -g 

Sails need to be installed globally on your machine since it plays a role of a CLI (Command Line Interface) so you will not only use it for creating and setting up the project but for other things concerning your project (for ex: deploying, lifting, generating Controllers).

For creating a new project using Sails-CLI we use the new command and give it the name of the project then relax grab a cup of coffee and le sails do the heavy job for you.

sails new sails-app

Make sure to cd to the directory where you want to create your sails app project, sails will create the folder for you with the supplied name and put all the sub-folder and configuration files ready for you with a simple app already created for you to see how things works.

Also when you try to create a sails project you will be prompted to choose between two templates:

  1. Web App: for creating a full web app already loaded with functions and features like (Auth, Login, 404 handlers.)
  2. Empty: this is for creating a boilerplate only project that has only the sails.js CLI and it's a standard configuration.

For this tutorial, we want to dive deep into sails and its base structure so we go with an Empty sails project.

App Structure

Sails project comes with a kind of unique and awesome project structure with some configuration already put on, if you are not a guy how looks and reads through other people's code a lot you mind find some difficulties to understand the structure.

api/ Where Controllers, Models and helpers live (handling API Requests and serve reponses).

assets/ All of you js, css and static resources are placed in here (for js and css it means you create your front-end app inside of this folder too this comes in handy for smaller apps).

config/ Sails.js system config files live in here so for customizing your application and adding any third-party modules or integrating middlewares, databases you will be configuring one of the files.

tasks/ the folder is a suite of Grunt tasks used for automating frequent tasks like bundlling assets or publishing some vendor files or even making the project ready for production use.

views/ All your app views, templates and layouts live in here Sails.js comes pre-installed and working with EJS but you can use your favorite template engine too.

.editorconfig Custom setup for the sails files for you code editor.
.eslintignore List of files, folders and patterns to be ignore by ESLint. 
.eslintrc ESLint custom configuration for your project files.
.gitignore Files, folders and patterns on which to be ignored by GIT stashing system.
.htmlhintrc Configuration for HTML hints and intellisense.
.sailrc Sails App Custom Configuration (You can customize and configure your app through this file).
app.js Main Entry point for your server which has some error handling and it does start the server.
Gruntfile.js Grunt Task manager custom configuration.
package.json Your Node.js App Packagejson.
README.md readme file for instructions and repos.

The main entry point for your Sails/Nodejs/Express Application is the app.js if you look inside the package.json you will see custom scripts for running, linting and testing your code.

Also, you can customize the Sails.js framework by defining custom configuration on the .sailrc.

Sail CLI

The Sails Command Line Interface plays a major role in assisting you thought out the development and deployment process of your application so you sit back and run commands that helps you manage your code and project.

There are many useful commands provided by the CLI.

 

Plenty of commands can really help you out and make it a bit easier for you.

Also, you can use the REPL Console which is normal Node.js/Javascript Console but it integrates with your sails server so you can easilly test and interect with you app environment with quick commands and it is specifically helpful when dealing with Models and databases.

Just Run:

sails console 

Sails MVC 

The MVC Architecture allows you to create extensible API endpoint for your front-end app and any other application that does need communicate with your server endpoint, where Sails fully support this architecture but not only that it also provides other systems and structures for having a smooth development experience plus creating maintainable and understandable code.

Routes are what tells sails/express to where to route the request but sails create a wrapper around the standard Express routes system which easily allows you to create Routes with all the configuration needed all in one place with simple commands, take a look on the following Route path that routes the request to a controller that is saved on the api/controllers/

{
  "get /todo/add": "TodoController.addNewTodo"
}

Here you are telling it the HTTP method and the route path then you where to redirect the HTTP Request (ControllerName.methodName).

Controllers are the heart of an MVC application since they do the request handling and make sure to deliver the response as expected back to the client.

You can use the generate command on Sails-CLI to quickly create and generate controllers, models or actions.

You create the controllers in the standard way where you would have a controller file sitting in the api/controllers folder and all the actions are inside that file or use the new way that sails offer which is much easier to follow and maintain your controllers which offers you to put a folder with the controller name inside the controllers folder and inside of that folder you put all of your actions each action in its own separate file.

in Sails, you can use the standard Express Controllers structure or you can use Action2 the new architecture introduced by Sails team using Node-Machine to create controllers are ready to read and maintain through the time where it implements the notion of one input and one exit for your controller.

Look at the noticeable differences between a standard express controller structure and the new Action2 method.

Standard Express

exports.addNewTodo = (req, res) => {
  return res.send("Todo Added!");
}

Action2 

/*api/controllers/todo/add.js*/
module.exports = {
  friendlyName: "Signup User",
  description: "Add a new Todo on your list",
  inputs: {
    name: {
      description: "Todo name",
      type: "string",
      required: true
    }
  },
  exits: {
    success: {
      responseCode: 201
    },
    invalidData: {
      description: "Please Fill in TODO name correctly!",
      responseCode: 500
    }
  },

  fn: async (inputs, exits) => {
    if (!inputs || !inputs.name) return exits.invalidData();
    const newTodo = await sails.models.todo
      .create(inputs)
      .intercept(err => {
        if (err) console.error("Cannot Created Todo!");
      })
      .fetch();
    console.log("New Todo has been created: ", newTodo);
    return exits.success(newTodo);
  }
};

If you try to read carefully thought out the Action2 code you see an object with some input and exist attributes plus a function (fn) attribute which gets executed as a controller handler taking the input and exit objects as parameters.

You can read more about Action2 method and Node-Machine from Here

Models are an interface for interacting and communicating with a database(s) and with Sails Waterline ORM you can use the ORM API to create a single code base and make it work with multiple database systems with different types (MySQL, MongoDB...).

All of you models will live inside of api/models folder and need to implement a specific schema for the Waterline ORM then it can be translated and compiled to your target database(s) in runtime.

Here is the following example of a Todo model and how you can call it and use it from the todo/add controller

/*The Attributes represents different things when depending on wich database system you are working with (Columns in MySQL) and (Key Attributes in MongoDB).*/
module.exports = {
  attributes: {
    name: { type: "string", required: true, allowNull: false },
    done: { type: "boolean", defaultsTo: false }
  }
};

All Models are global by default on Sails so you don't have to import your created model they will be automatically available for you during the running on your controllers once you need them.

so just type the name of the controller or you can access it through the sails global variable that is available all over your application.

//Action2 main function from todo/add.js 
fn: async (inputs, exits) => {
  if (!inputs || !inputs.name) return exits.invalidData();
  //We access te todo model through the sails.models global variable
  const newTodo = await sails.models.todo
    .create(inputs)
    .intercept(err => {
      if (err) console.error("Cannot Created Todo!");
    })
    .fetch();
  /*Then you can use the Waterline API for talking with your database(s)*/
  console.log("New Todo has been created: ", newTodo);
  return exits.success(newTodo);
}

 Make sure to check out the Waterline ORM Docs for more information about the API and how to communicate with the database.

Middlewares

Middlewares are a piece of function that runs before your controllers and actions does, for example, to provide meta-data to your controllers (You can use it for Authenticating users) in Sails they work the same way the does on Express but in a much meaningful way.

All of you sails middlewares will live inside of config/http.js there you can define your middleware function which takes (request, response, next) objects as a standard express middleware but the best part in here is you can actually define them in an arbitrary order but then you use the order object provided by sails which allow you to change and alter the order of which your middleware functions run.

order: [
  "cookieParser",
  "session",
  "bodyParser",
  "compress",
  "poweredBy",
  "router",
  "www",
  "favicon",
  "logIpAddress"
],

/*Here you define a self executing function that returns the actuall middleware function to be able to do some initialization, you can use it the standard way though.*/
logIpAddress: (() => {
  console.log("Initializing LogIpAddress Middleware...");
  return (req, res, next) => {
    console.log(
      "Client Ip: ",
      req.headers["x-forwarded-for"] || req.connection.remoteAddress
    );
  };
})()
}

 Make sure to include your middleware in the order array in order to get executed.

Also, all the pre-defined middleware are very sensitive so if you will to remove one from the list or change the order it may make a whole difference on how you Sails application will work and operate.

 

Share Tutorial

Made With By

Ipenywis Founder, Game/Web Developer, Love Play Games