官术网_书友最值得收藏!

Mounting subapplications

Each Express application is a middleware on its own, so it can be mounted into another application. This feature makes it easy to plug subapplications into a parent one. Possible use cases include the following points:

  • Creating applications in a modular way, where each subapplication is totally independent of the others and possibly developed by other team members
  • Adding a blogging platform or a forum to an endpoint
  • Integrating third-party tools such as a monitoring dashboard or an FTP client along with a text editor

There are two possible approaches we can take when working with mountable applications: either the main application deals with crosscutting concerns such as logging and error handling, or the subapplications handle these things on their own. If we require third-party applications, we might not be able to control some of these aspects, but if we are creating a modular web application from scratch, then it's our choice to begin with.

Next, we will create an example application on how to mount a subapplication and discuss what the advantages are and the problems we might bump into.

We will create three files in the same folder: an index.js file for the main application and two other files, blog.js and admin.js, for the subapplications (let's assume we are plugging in an admin dashboard and a blog system). The main application will be light and it will only load the other two:

var express = require('express');
var app = express();

var blog = require('./blog');
var admin = require('./admin');

app.use('/blog', blog);
app.use('/admin', admin);

app.listen(7777);

Generally, when mounting applications, we specify a path for each application, as is the case in the preceding example. The blog and admin applications are small, since we are focusing here on the mounting feature instead of creating complex applications. The following sample code is for the blog subapplication (the admin one is similar):

var express = require('express');
var app = express();

app.get('/', function(req, res, next) {
  res.send('Blog app says hello');
});

app.get('/error', function(req, res, next) {
  return next(new Error('err'));
});

app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.send('BLOG: an error occured');
});

module.exports = app;

Note

With the new Express 4 router, we can use express.Router() instead of express() to create a mountable application.

As you might have noticed, these two applications don't bind to a port because that's the job of the master application. Also, they are decoupled from the main application and can use their own rendering engine, settings, and other features.

By using a simple comment or an if statement, we can disable or enable their inclusion, making it easy to use this system for feature flags. Instead of creating these modular applications, if we would have made a big monolith, it would have been harder to switch off the /blog or /admin endpoints.

There are some things we need to take into consideration with mountable applications, which are as follows:

  • Avoid code duplication; for example, if we intend to use a logging solution for all the endpoints, it would be better to include it in the parent application
  • If we want to redirect to an absolute path, then the argument must start with a forward slash (/); otherwise, for a relative path, we should omit it
  • If the applications need to share sessions, then the master application should load them
  • When creating general-purpose applications, it's a good thing to move them into their separate repositories and publish them to the NPM registry; other people and projects may need them

Note

The middleware that used to come bundled with Express are self-aware, meaning they are not loaded twice. Each of them makes a check to see whether the function has been called previously (using some kind of flag), similar to what the session middleware does:

// self-awareness
if (req.session) return next();

This means that if a middleware function has been loaded in the master application, it won't do the same work in the subapplications.

主站蜘蛛池模板: 临江市| 自贡市| 长武县| 壤塘县| 肇州县| 即墨市| 沙雅县| 临高县| 法库县| 广汉市| 南华县| 七台河市| 海安县| 启东市| 平利县| 遵化市| 平江县| 岳阳县| 金寨县| 芮城县| 略阳县| 浦县| 清徐县| 安吉县| 长春市| 阿合奇县| 罗源县| 临湘市| 青岛市| 灌阳县| 九江县| 南阳市| 怀集县| 甘南县| 卓尼县| 华池县| 台州市| 桃园县| 棋牌| 方正县| 安国市|