Using more than one app in express, with req.app, res.app, and require

In express.js I get into situations in which I am dealing with more than one instnace of an express app object. This is helpful, and to some extent necessary as it helps break things down into more manageable smaller components that are each responsible for a certain task, such as rendering, or grabbing settings from a yaml or json file. In this post I will be writing about req.app, res.app which are both just reference the instance of app that is using the middleware. This can be used as a way to not use require to get a reference to my main app instance from another file, but that is another way of pulling it off. In other words this post is about instances of the app object in express, and how to manage a bunch of theme when starting to make something a little complicated.

1 - what to know before hand

This is a post on working with app objects in express.js using req.app, it is not a getting started post on express.js, or any additional skills required before hand. If you are new to express, or you just want to check out my main post on express that might be a good starting point.

2 - The req.app demo

The req.app, and res.app properties each hold the same reference to the app that is using a middleware method. For an example of how this can be useful, I made two javaScript files. One file is the usual main app.js file, and the other presents a single middleware method that renders a view. In the middleware I create a separate instnace of an express app, but I want to set some settings from the main app.js file. One way to do this is to use res.app to set values in the middleware app to what is in the main app.

2.1 - Setup

For this demo I just need to install express.

1
2
3
4
$ mkdir response-app
$ cd response-app
$ npm init
$ npm install express --save

2.1 - The main /app.js file

Here in the main app.js file I create an instance of an app object, and set some app settings with app.set. I then just require a single middleware function called otherapp.js that will do the rendering, but it needs some values that I have set here. There are a few ways to do it, but in this demo I will be using res.app.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let express = require('express'),
path = require('path'),
// the main app instance
app = express();
app.set('id','main');
app.set('port',8080);
// path and view engine
app.set('views', path.join(__dirname, 'view'));
app.set('view engine', 'ejs');
app.use(require('./otherapp.js'));
app.listen(app.get('port'), function () {
console.log('express demo is up on port: ' + app.get('port'));
});

2.2 - The /otherapp.js file

This is the single middleware method that the main app is using with app.use. In here I am using res.app to gain a reference to the main app object instance in app.js. I am then setting the settings of another instance of the app object in the middleware to the settings in the main app.js file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let express = require('express'),
renderApp = express();
module.exports = function (req, res) {
let app = res.app;
// copy over settings from main app
// including views path, and engine
Object.keys(app.locals.settings).forEach(function (key) {
renderApp.set(key, app.get(key));
});
// preserve id
renderApp.set('id', 'render');
res.render('index', {
settings: {
app: app.locals.settings,
renderApp: renderApp.locals.settings
}
});
};

2.3 - The /view/index.ejs file

Finally I have a single index.ejs file in the view folder that will be rendered by the middleware method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<h1>Express Project Settings</h1>
<h2>Main App:</h2>
<ul>
<% Object.keys(settings.app).forEach(function(key){ %>
<li>key: <%= key %> : <%= settings.app[key] %></li>
<% }); %>
</ul>
<h2>Render App:</h2>
<ul>
<% Object.keys(settings.renderApp).forEach(function(key){ %>
<li>key: <%= key %> : <%= settings.renderApp[key] %></li>
<% }); %>
</ul>