Sails.js in Action
Mike McNeil and Irl Nathan
  • MEAP began May 2015
  • Publication in February 2017 (estimated)
  • ISBN 9781617292613
  • 500 pages (estimated)
  • printed in black & white

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. You'll follow perfectly-paced, gap-free instruction as you learn to build up the back end of a typical Single Page Web Application. As you hone your skills, you'll explore advanced features like services, hooks, and file uploads. Along the way, you'll come to fully understand Node's asynchronous programming model and the syntax and conventions used to implement it.

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

About the Technology

Node.js has rapidly become a viable choice for large-scale web applications that previously relied on Java, PHP, or Rails. Sails.js is a modern MVC framework for Node that radically simplifies back-end web development. As you'd expect from any modern framework, Sails provides full support for data access, real-time programming with web sockets, enterprise-caliber security, and modern development workflow patterns. You also get powerful productivity features like rapid API development via Sails blueprints, task automation via node-machines, and easy integration with front-end frameworks like Ember and Angular.

What's inside

  • Create and deploy powerful back-end APIs using Sails
  • Add real-time web socket events to your projects
  • Deploying production apps
  • User Management and Authentication
  • Using Sails blueprints in your workflow
  • Integrating Front-end frameworks like Angular and Ember with Sails
  • The Leading MVC Framework for Node.js

About the reader

Readers should be comfortable with JavaScript and front-end web development. Perfect for back-end developers making the transition to JavaScript and Node.

About the authors

Mike McNeil is an open-source developer based in Austin, TX, and the creator of Sails.js. He is the co-founder of Balderdash, a mobile and web studio, an avid contributor to many popular open source projects, and a speaker at numerous conferences including Powered by Javascript, All Things Open, NodePDX, Geeklist #hack4good in Paris, DevOpsDays, and NodeJS Conf Italy. Irl Nathan is the producer of Sailscasts a successful 50+ part series focusing on web programming using Sails. He's a recovering lawyer who now works with Mike and is a co-founder of Treeline.

Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
  • MEAP combo $49.99 pBook + eBook
  • MEAP eBook $39.99 pdf + ePub + kindle

FREE domestic shipping on three or more pBooks