Sails.js in Action
Mike McNeil and Irl Nathan
  • January 2017
  • ISBN 9781617292613
  • 488 pages
  • printed in black & white

Look no further - you've found the ultimate source.

Damien White, Visoft

Sails.js in Action is a comprehensive guide to building enterprise-capable web applications using Node and Sails. Written by the creators of the Sails.js framework, this book carefully introduces each concept, technique, and tool with real-world examples and crystal clear explanations.

About the Technology

Sails makes professional web development a breeze. This instantly familiar MVC framework automatically handles the tedious application boilerplate, so you can concentrate on developing features and creating business value. You get powerful tools for rapid API development, task automation, an ORM, and easy integration with any web, mobile, or IoT frontend. And because you're using Node.js, it's JavaScript all the way down.

About the book

Sails.js in Action is a comprehensive guide on how to build enterprise-capable web applications. Written by the creators of Sails.js, this book introduces each concept and technique with real-world examples and thorough explanations. As you read, you'll learn to build the backend of a typical web application while you explore real-time programming with WebSockets, security fundamentals, and best practices for building Sails/Node.js apps.

Table of Contents detailed table of contents

1. Getting Started

1.1. What is Sails?

1.2. What can you build with Sails?

1.3. So why Sails?

1.4. Fundamental concepts of a web application

1.4.1. Requests and responses

1.4.2. HTTP methods

1.4.3. Routing

1.4.4. Performing actions

1.5. Understanding databases

1.5.1. What's in a Sails model?

1.5.2. Sails model methods

1.6. Putting it all together in a back-end API

1.6.1. Other types of routes

1.7. Our back-end design philosophy

1.7.1. Starting with just the front-end code

1.7.2. Prototyping with blueprints

1.7.3. Finalizing your API

1.8. Delivering front-end assets

1.9. Front-end vs. back-end validations

1.10. Realtime (WebSockets)

1.11. Asynchronous programming

1.12. Meet Chad

1.13. Summary

2. First Steps

2.1. Tools of the trade

2.1.1. Mac, Windows, and Linux…​ oh my!

2.1.2. Choosing a text editor versus an IDE

2.1.3. "Must have" tools

2.1.4. Whoa, command-line? Terminal? W-what?

2.1.5. Installing Node

2.1.6. Installing Sails

2.2. How code is organized in Node.js

2.2.1. What is a Node module?

2.2.2. Creating our first Sails application

2.2.3. Using a module from NPM

2.2.4. Starting the Sails server

2.2.5. What is localhost:1337?

2.2.6. Killing the server

2.3. Online resources for this book

2.3.1. Git and GitHub

2.3.2. Installing Git

2.3.3. What is a GitHub repo?

2.3.4. Cloning a repo

2.4. Documentation and community support

2.5. Summary

3. Using Static Assets

3.1. Introduction to static routing

3.1.1. The default homepage

3.1.2. Replacing the default homepage

3.2. The asset pipeline

3.2.1. A quick look at the .tmp/ folder

3.2.2. Grunt: The other white meat

3.2.3. Putting it all together: Chad's sweet homepage

3.2.4. Using a CDN

3.2.5. Why index.html?

3.2.6. An <img>is worth a thousand words

3.2.7. Relative paths

3.3. Managing scripts and stylesheets

3.3.2. Built-in LESS support

3.4. Front-end first API design

3.4.1. Identifying back-end requirements

3.5. Using Sails with jQuery

3.5.1. Example: listing data with jQuery

3.5.2. Example: jQuery form

3.6. Using Sails with Angular

3.6.1. Example: listing data with Angular

3.6.2. Example: Angular form

3.7. Summary

4. Using the Blueprint API

4.1. Prototyping with blueprints

4.1.1. Designing an API around a user interface

4.1.2. Obtaining the example materials for this chapter

4.1.3. Generating an API in Sails

4.1.4. First look at Sails auto-migrations

4.2. Shortcut blueprint routes

4.2.1. Creating records with blueprint shortcut routes

4.2.2. Accessing the database from the URL bar

4.3. Connecting the front-end to our new API

4.3.1. Finding records with AJAX

4.3.2. Creating a record with AJAX

4.4. Exploring the REST of the blueprint API

4.4.1. Locating a particular record with AJAX

4.4.2. Updating a record with AJAX

4.4.3. Deleting a record with AJAX

4.5. Upgrading to WebSockets

4.5.1. Replacing $http.get() with io.socket.get()

4.5.2. Replacing $ with

4.6. Summary

5. Custom Back-End Code

5.1. Chad has a new investor

5.1.1. Converting requirements into development tasks

5.2. Running code on lift

5.2.1. Using bootstrap.js

5.3. A deeper understanding of model methods

5.3.1. Using the Video.count()model method

5.4. Introducing machinepacks

5.4.1. Finding a package to work with the YouTube API

5.4.2. Installing a machinepack

5.4.3. Exploring NPM

5.4.4. Using machines

5.4.5. Understanding machine inputs

5.4.6. Setting your own custom configuration inlocal.js

5.4.7. Using custom configuration in your code

5.4.8. Understanding machine exits

5.4.9. Using callbacks

5.4.10. Marshaling data

5.5. Creating multiple records

5.6. Summary

6. Using Models

6.1. Understanding Sails models

6.2. Managing user data

6.2.1. Obtaining the example materials for this chapter

6.2.2. A front-end first approach to data modeling

6.2.3. Building a signup page

6.2.4. Building a user profile page

6.2.5. Building an admin interface

6.2.6. Recovering data after a soft delete

6.3. Creating a new model

6.3.1. Running the generator

6.3.2. Creating our first record

6.4. Demystifying databases

6.4.1. Models, connections, and adapters

6.4.2. Configuring a database

6.4.3. Defining attributes

6.4.4. Attribute validation

6.4.5. Handling existing data with Sails auto-migrations

6.4.6. Filtering data returned by blueprints

6.5. Understanding model methods

6.5.1. Anatomy of a Sails model method

6.5.2. The .create() model method

6.5.3. The .find() model method

6.5.4. The .update() model method

6.5.5. The .destroy() model method

6.5.6. The .count() model method

6.6. Summary

7. Custom Actions

7.1. Demystifying routes and actions

7.1.1. Introducing res.json()

7.1.2. Automatic routing for custom actions

7.2. Identifying the requirements for our custom actions

7.2.1. Obtaining the example materials for this chapter

7.3. Handling a signup form

7.3.1. Naming custom actions

7.3.2. Creating an action

7.3.3. Introducing req.param()

7.3.4. Validating email addresses

7.3.5. Encrypting passwords

7.3.6. Profile images with Gravatar

7.3.7. Creating user records

7.3.8. Preventing duplicate accounts

7.3.9. Understanding response methods

7.3.10. Quick diversion: adding a dummy user in bootstrap.js

7.4. Providing data for a user profile page

7.4.1. Retrieving user profile information

7.4.2. Permanently deleting a user

7.4.3. Soft-deleting a user record

7.5. Restoring user accounts

7.5.1. Building an action to restore a user profile

7.6. Editing user profiles

7.6.1. Retrieving the record for a particular user

7.6.2. Retrieving a user's Gravatar URL

7.6.3. Saving updated profile information

7.6.4. Updating a user's password

7.7. Administrative actions

7.7.1. Listing all the users in the database

7.7.2. Updating administrative flags

7.8. Summary

8. Server-Rendered Views

8.1. Page navigation

8.1.1. Client-side vs. server-side routing

8.1.2. What is a server-rendered view?

8.1.3. Obtaining the example materials for this chapter

8.2. Personalizing web pages

8.2.1. A review of explicit routes

8.2.2. Defining an explicit route

8.2.3. Using EJS views

8.2.4. Using partials and layout.ejs

8.2.5. Exposing data for use in client-side JavaScript

8.2.6. Hard-coding locals in a route

8.3. Transitioning from an SPA

8.4. Summary

9. Authentication and Sessions

9.1. What is authentication?

9.2. The login process

9.2.1. Obtaining the example materials for the chapter

9.2.2. Understanding the back-end for a login form

9.2.3. Creating a /login route

9.2.4. Handling a login form

9.2.5. What does "stateless" mean?

9.2.6. Understanding the Sails session

9.2.7. Saving the user's logged-in status

9.2.8. Creating the logout endpoint

9.2.9. Updating the session when a user is deleted or restored

9.2.10. Authenticating a user after signup

9.2.11. Configuring the session store

9.3. Personalizing page content for logged-in users

9.3.1. Introducing PageController

9.3.2. Using a custom action to serve the homepage

9.4. Implementing the back-end application flow

9.4.1. Personalizing our list of videos

9.4.2. Securing our administration page

9.4.3. Personalizing the user profile page

9.4.4. Securing the edit profile form

9.4.6. Implementing business rules for the signup page

9.5. Summary

10. Policies and Access Control

10.1. A farewell to blueprints

10.1.1. Obtaining the example materials for this chapter

10.1.2. Designing custom back-end endpoints

10.1.3. More explicit routes

10.1.4. Disabling blueprint routes

10.2. Policies

10.2.1. What is a policy?

10.2.2. Creating a policy

10.2.3. Configuring policies

10.2.4. Best practices

10.2.5. Preventing an inconsistent user experience

10.2.6. Restricting access to account management endpoints

10.2.7. Preventing users from messing with each others' data

10.2.8. Preventing confusion for signed-in users

10.2.9. Restricting access to administrative actions

10.3. Summary

11. Refactoring

11.1. Maintaining your sanity when requirements change

11.1.1. Obtaining and revising requirements

11.1.2. Organizing views into five categories

11.1.3. Obtaining the example materials for this chapter

11.1.4. Refactoring navigation

11.1.5. Refactoring views

11.2. Custom routing and error pages

11.2.1. The impact of :variables in routes

11.2.2. Customizing Sails built-in response pages

11.3. Adjusting access control rules

11.3.1. Customizing a view based on edit permissions

11.4. Patterns and best practices

11.4.1. Refactoring repetitive action names

11.4.2. Using folders to organize views

11.4.3. Refactoring EJS views and client-side templates

11.4.4. Using async.each()

11.4.5. Adding new features

11.5. In Depth: Adding a password recovery flow

11.5.1. Understanding how password recovery works

11.5.2. Sending emails

11.6. Summary

12. Embedded Data and Associations

12.1. Obtaining the example materials for this chapter

12.2. Understanding relationships between data

12.2.1. Brushfire models after the pivot

12.2.2. Relationships between models

12.3. Associating data using embedded JSON

12.3.1. Setting up an embedded relationship

12.3.2. Creating a record with embedded JSON

12.3.3. "Populating" embedded data

12.3.4. Updating a record with embedded data

12.4. Understanding Sails associations

12.4.1. Configuring an association between two models

12.4.2. Using .add(), .remove(), and .save()

12.4.3. Using via to create a two-way association

12.4.4. Refactoring an action to use associations

12.4.5. Using .populate()

12.4.6. Refactoring bootstrap.js to use associations

12.5. Using services

12.5.1. Example: Using associations for the tutorial detail page

12.5.2. Using a service to consolidate duplicative code

12.6. Summary

13. Ratings, Followers, and Search

13.1. Obtaining the example materials for this chapter

13.2. Incorporating ratings

13.2.1. Calculating averages

13.2.2. Adding a new rating

13.3. Implementing videos

13.3.1. The "Create video" form

13.3.2. Review: adding a record to a collection association

13.3.3. Editing video details

13.3.4. Managing the sort order of videos using an embedded array

13.3.5. Integrating a video player

13.3.6. Cascading delete

13.3.7. Removing a record from a collection

13.4. Implementing support for followers

13.4.1. The follow and unfollow endpoints

13.4.2. Displaying a user's followers on her profile

13.5.1. Paginating search results

13.5.2. General pagination

13.6. Summary

14. Real time with WebSockets

14.1. Obtaining the example materials for this chapter

14.2. Understanding WebSockets

14.2.1. Establishing a socket connection

14.2.2. Virtual requests

14.3. Implementing chat

14.3.1. Creating a chat API

14.3.2. Adding chat to an existing page

14.3.3. Subscribing a socket to a room

14.3.4. Sending a chat notification

14.3.5. Adding a chat event listener to the front-end

14.4. Sending "typing" and "stoppedTyping" notifications

14.4.1. Listening for different kinds of notifications

14.4.2. Excluding the sender from a broadcast

14.4.3. Other useful methods in sails.sockets

14.5. Understanding Resourceful PubSub (RPS)

14.5.1. Using.subscribe()

14.5.2. Using .publishUpdate()

14.5.3. RPS methods and event names

14.6. Understanding how the blueprint API uses RPS methods

14.6.1. The find and findOne actions

14.6.2. The create action

14.6.3. The update action

14.6.4. The destroy action

14.6.5. The populate action

14.6.6. The add action

14.6.7. The remove action

14.7. Summary

15. Deployment, Testing, and Security

15.1. Obtaining the example materials for this chapter

15.2. Deploying your Sails app

15.2.1. About Heroku

15.2.2. Scaling to multiple dynos

15.2.3. Installing the Heroku toolbelt

15.2.4. Using a remote PostgreSQL database

15.3. Using environment variables with Sails

15.3.1. Storing credentials in environment variables

15.3.2. Configuring a connection to a remote database

15.3.3. Accessing environment variables in custom code

15.4. Runtime environments

15.4.1. Setting a default datastore for production

15.4.2. Configuring auto-migration settings

15.4.3. Creating tables in PostgreSQL

15.4.4. Runtime vs. "build-time"

15.4.5. Setting up Grunt for production

15.4.6. Deploying to Heroku

15.5. Configuring sessions and sockets for production

15.5.1. Provisioning a remote "Redis To Go" instance

15.5.2. Configuring a remote session store

15.5.3. Using Redis to deliver notifications

15.5.4. Using Redis in development (so you don't have to log in all the time)

15.5.5. Configuring Mailgun for email delivery

15.6. Testing

15.6.1. Installing dependencies for your test suite

15.6.2. Using before() and after()

15.6.3. Running tests from the command line

15.6.4. Configuring your test environment

15.6.5. Understanding tests

15.6.6. Testing an endpoint

15.6.7. Refactoring a test using fixtures and helper functions

15.6.8. Testing model methods and validations

15.7. Security

15.7.1. Front-end, network and back-end security

15.7.2. Understanding cross-site scripting (XSS) attacks

15.7.3. Protecting against XSS attacks

15.7.4. Understanding cross-site request forgery (CSRF) attacks

15.7.5. Enabling CSRF token protection

15.7.6. Sending the CSRF token

15.7.7. Disabling CSRF protection in tests

15.7.8. Understanding cross-origin resource sharing (CORS)

15.7.9. Understanding "man-in-the-middle" attacks (MIM)

15.7.10. Denial of service (DoS) attacks

15.7.11. SQL injection attacks

15.8. Summary


Appendix A: A brief history of Sails

A.1. A brief history of Sails

A.2. The second "renaissance" in web development

What's inside

  • Creating the backend for a web, mobile, or IoT app
  • Real-time programming with WebSockets
  • User management, authentication, and password recovery
  • Using Sails to autogenerate REST APIs
  • Custom backend development and third-party API integrations

About the reader

Readers should be comfortable with JavaScript and frontend web development.

About the authors

Mike McNeil is the creator of Sails.js. Irl Nathan is the producer of sailsCasts, a series focused on using Sails.

placing your order...

Don't refresh or navigate away from the page.
print book $34.99 $49.99 pBook + eBook + liveBook
Additional shipping charges may apply
Sails.js in Action (print book) added to cart
continue shopping
go to cart

eBook $27.99 $39.99 3 formats + liveBook
Sails.js in Action (eBook) added to cart
continue shopping
go to cart

Prices displayed in rupees will be charged in USD when you check out.

FREE domestic shipping on three or more pBooks