Middleware

Sails is fully compatible with Express / Connect middleware - in fact, it's all over the place! Much of the code you'll write in Sails is effectively middleware; most notably controller actions and policies.

HTTP Middleware

Sails also utilizes an additional configurable middleware stack just for handling HTTP requests. Each time your app receives an HTTP request, the configured HTTP middleware stack runs in order.

Note that this HTTP middleware stack is only used for "true" HTTP requests-- it is ignored for virtual requests (e.g. requests from a live Socket.io connection.)

Legend:
  • * - The middleware with an asterisk (*) above should almost never need to be modified or removed. Please only do so if you really understand what you're doing.

Adding or Overriding HTTP Middleware

To configure a custom HTTP middleware function, define a new HTTP key sails.config.http.middleware.foobar and set it to the configured middleware function, then add the string name ("foobar") to your sails.config.http.middleware.order array wherever you'd like it to run in the middleware chain (a good place to put it might be right before "cookieParser"):

E.g. in config/http.js:

  // ...
  middleware: {

    // Define a custom HTTP middleware fn with the key `foobar`:
    foobar: function (req,res,next) { /*...*/ next(); },

    // Define another couple of custom HTTP middleware fns with keys `passportInit` and `passportSession`
    // (notice that this time we're using an existing middleware library from npm)
    passportInit    : require('passport').initialize(),
    passportSession : require('passport').session(),

    // Override the conventional cookie parser:
    cookieParser: function (req, res, next) { /*...*/ next(); },


    // Now configure the order/arrangement of our HTTP middleware
    order: [
      'startRequestTimer',
      'cookieParser',
      'session',
      'passportInit',            // <==== passport HTTP middleware should run after "session"
      'passportSession',         // <==== (see https://github.com/jaredhanson/passport#middleware)
      'bodyParser',
      'compress',
      'foobar',                  // <==== we can put this stuff wherever we want
      'methodOverride',
      'poweredBy',
      '$custom',
      'router',
      'www',
      'favicon',
      '404',
      '500'
    ]
  },

  customMiddleware: function(app){
     //Intended for other middleware that doesn't follow 'app.use(middleware)' convention
     require('other-middleware').initialize(app);
  }
  // ...

Express Middleware In Sails

One of the really nice things about Sails apps is that they can take advantage of the wealth of already-existing Express/Connect middleware out there. But a common question that arises when people actually try to do this is:

"Where do I app.use() this thing?".

In most cases, the answer is to install the Express middleware as a custom HTTP middleware in sails.config.http.middleware. This will trigger it for ALL HTTP requests to your Sails app, and allow you to configure the order in which it runs in relation to other HTTP middleware.

Express Routing Middleware In Sails

You can also include Express middleware as a policy- just configure it in config/policies.js. You can either require and setup the middleware in an actual wrapper policy (usually a good idea) or just require it directly in your policies.js file. The following example uses the latter strategy for brevity:

{
  '*': true,

  ProductController: {

    // Prevent end users from doing CRUD operations on products reserved for admins
    // (uses HTTP basic auth)
    '*': require('http-auth')({
      realm: 'admin area'
    }, function customAuthMethod (username, password, onwards) {
      return onwards(username === "Tina" && password === "Bullock");
    }),

    // Everyone can view product pages
    show: true
  }
}