Advanced Routing

Brian edited this page Dec 11, 2016 · 1 revision

With the release of 0.8.0 PencilBlue introduced a fully refactored routing engine that allows developers to take control over the entire request pipeline. When PencilBlue starts, it registers the default set of middleware. Later during plugin initialization, plugins will be able to manipulate the request pipeline by adding, replacing, or removing middleware in the onStartupWithContext function in the main module file of the plugin.

The framework provide numerous ways to configuring the pipeline. This is done by naming each piece of middleware that is registered. Tracking them by unique names allows for the framework to insert, replace, or remove middleware at any point in the pipeline. This also makes request tracing a possibility despite the asynchronous nature of server-side JS.

In order to demonstrate the power of the new framework we've provided a few examples. Let's take a look...

The first example looks at how to add middleware. We are simply injecting in code into the request pipeline that will add a CORS header for every incoming request.

/**
 * An example of adding middleware.  
 * It injects code into the request pipeline that adds a header to allows resources from the server to be accessed by other domains.
 */
class CorsPlugin {
  
  static onStartupWithContext (context, cb) {
    
    var middlewareName = 'addCorsHeader';
    var middleware = {
      name: middlewareName,
      action: MinifyPlugin.addCorsHeader
    };
    var result = pb.Router.addMiddlewareBefore('checkPublicRoute', middleware);
    cb(!result ? new Error('Failed to add middleware') : null);
  }
    
  static addCorsHeader (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
  }
}

The second example demonstrates how to remove middleware that is not desired. While the majority of default middleware is necessary it is possible to remove the less critical components. CAUTION: only remove middleware if you have a firm grasp of how the Router code works. Removing the wrong middleware could have serious consequences on security, performance, and stability.

/**
 * An example of removing middleware.  
 * It removes the middleware that writes the request result to the console
 */
class PerformancePlugin {
  
  static onStartupWithContext (context, cb) {
    
    var middlewareName = 'responseTime';
    var result = pb.Router.removeMiddleware(middlewareName);
    cb(!result ? new Error('Failed to remove middleware') : null);
  }
}

The last example looks at how to replace existing middleware to customize behavior. The code determines if the outgoing result is JS. When this condition is TRUE the code will attempt to minify the result before writing it out to the response stream. Otherwise, the original middleware is executed.

/**
 * An example of replacing middleware.  
 * It injects code into the request pipeline that will minify JS before being written to the response stream
 */
class MinifyPlugin {
  
  static onStartupWithContext (context, cb) {
    
    var middlewareName = 'writeResponse';
    var middleware = {
      name: middlewareName,
      action: MinifyPlugin.writeResponseWithMinification
    };
    var result = pb.Router.replaceMiddleware(middlewareName, middleware);
    cb(!result ? new Error('Failed to override middleware') : null);
  }
    
  static writeResponseWithMinification (req, res, next) {
    var data = req.controllerResult;
    if (data.content_type === 'text/javascript' && !!data.content) {
      data.content = UglifyJS.minify(data.content, {fromString: true});
    }
    pb.Middleware.writeResponse(req, res, next);
  }
}
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.