Middleware

Sean Kennedy edited this page Dec 17, 2016 · 7 revisions

Middleware services are special services specifically for express middleware. Rather than being loaded at server startup based on dependencies, middleware is explicitly loaded by the middleware service based on the order the middleware is listed in the middleware property of the config. 'Post handler' middleware that is loaded after all other middleware (including express handlers) can be specified in the middleware$ property of the config.

"express": {
  "middleware": ["csrf", "cors", "session"],
  "middleware$": ["errors"]
 }

The middleware modules are loaded out of the middleware directory of the app. They're similar to normal services except, like handlers, they can reference the express app through the app parameter of the init call. While middleware services can reference other services using dependency injection, other services won't be able to reference the middleware.

exports.init = function(app, callback) {
   app.use(...);

External Middleware Services

BlueOak Server can also load middleware from node_modules. External middleware is included in the config by its name from its package.json file.

bos-passport is an example of a BlueOak Server middleware node module.

Built-in Middleware Services

CORS

Use CORS to configure Cross-Origin Resource Sharing. See Node's CORS module for available options.

CSRF

Enables origin-based cross site request forgery protection. Rather than the traditional token-based protection, this checks the browser's Origin header against a white list of acceptable hosts to determine whether a given request is allowed.

To configure, specify an array of all the allowed origins.

"csrf": {
    "allowedOrigins": ["http://localhost:3000"]
}

Session

Enables a cookie-based session. The session configuration requires one or more keys used to sign the cookie.

"session": {
    "keys": ["sessionkey"]
}

Once enabled, the session can be accessed through the request object. See the cookie-session documentation for more information.

Body parser

Enabled the express body-parser on all routes.

Body parser supports four types: urlencoded, json, raw, text, which each have their own options. One or more of the types can be enabled by including the appropriate field in the body-parser config. However, keep in mind that settings like verify and reviver cannot be configured through this service. If such functions are needed, it's better to write a custom middleware service for that use.

Additionally there might be situations where it's necessary to use different parsers for different routes. That scenario will require a custom solution.

Example to enable and configure both json and urlencoded parser.

"body-parser": {
  "json": {
    "strict": true
  },

  "urlencoded": {
  }
}

Express-Static

Use express-static for serving static files. Set the www field to the directory containing the files. The directory is relative to the root application directory.

 "express-static": {
    "www": "assets"
  }

Monitor

Use the monitor middleware to enable counts and response time calculations on all express endpoints. It will convert the route to a namespace and record information about the request, including the request type and status code. For example, a GET request to a route /foo/:bar will cause a count event to express.GET.foo.bar.status_code.200 and a timing event to express.GET.foo.bar.response_time.

The prefix used when recording the stats can be configured. By default it's set to express.

"express-monitor": {
  "prefix": "myPrefix"
}

Alternatively express monitoring can be enabled on specific routes by using the express method of the monitor service.

app.get('/hello', monitor.express('myPrefix'), function(req, res) {
  ...
}

###Multer If you use multipart/form-data for file uploads, you will need to set up a multer config to tell BOS how to handle that. The config options can be found here: https://www.npmjs.com/package/multer#multeropts. Example config:

"multer": {
    "storage": "multerMemoryStorage" 
  }

The 'multerMemoryStorage' option inits multer with multer.memoryStorage()