express.Router
Use the express.Router
class to create modular, mountable route handlers. A Router
instance is a complete middleware and routing system; for this reason, it is often referred to as a “mini-app”.
The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app.
Create a router file named birds.js
in the app directory, with the following content:
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})
module.exports = router
Then, load the router module in the app:
var birds = require('./birds')
// ...
app.use('/birds', birds)
The app will now be able to handle requests to /birds
and /birds/about
, as well as call the timeLog
middleware function that is specific to the route.
Configurable middleware
If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters.
File: my-middleware.js
module.exports = function (options) {
return function (req, res, next) {
// Implement the middleware function based on the options object
next()
}
}
The middleware can now be used as shown below.
var mw = require('./my-middleware.js')
app.use(mw({ option1: '1', option2: '2' }))
Refer to cookie-session and compression for examples of configurable middleware.
---------------------------------------------------------------------------------------------------------------------------
server/index.js
const express = require('express');
const createError = require('http-errors');
const path = require('path');
const configs = require('./config');
const SpeakerService = require('./services/SpeakerService');
const app = express();
const config = configs[app.get('env')];
const speakerService = new SpeakerService(config.data.speakers);
app.set('view engine', 'pug');
if(app.get('env') === 'development') {
app.locals.pretty = true;
}
app.set('views', path.join(__dirname, './views'));
app.locals.title = config.sitename;
const routes = require('./routes');
app.use(express.static('public'));
app.get('/favicon.ico', (req, res, next) => {
return res.sendStatus(204);
});
app.use(async (req, res, next) => {
try {
const names = await speakerService.getNames();
res.locals.speakerNames = names;
return next();
} catch(err) {
return next(err);
}
});
app.use('/', routes({
speakerService
}));
app.use((req, res, next) => {
return next(createError(404, 'File not found'));
});
app.use((err, req, res, next) => {
res.locals.message = err.message;
const status = err.status || 500;
res.locals.status = status;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(status);
return res.render('error');
});
app.listen(3000);
module.export = app;
server/routes/index.js
const express = require('express');
const router = express.Router();
const speakersRoute = require('./speakers');
const feedbackRoute = require('./feedback');
module.exports = (param) => {
const { speakerService } = param;
router.get('/', async (req, res, next) => {
const speakerslist = await speakerService.getListShort();
return res.render('index', {
page: 'Home',
speakerslist,
});
});
router.use('/speakers', speakersRoute(param));
router.use('/feedback', feedbackRoute(param));
return router;
};
server/routes/speakers/index.js
const express = require('express');
const router = express.Router();
module.exports = (param) => {
const { speakerService } = param;
router.get('/', async (req, res, next) => {
const speakerslist = await speakerService.getList();
return res.render('speakers', {
page: 'All Speakers',
speakerslist
});
});
router.get('/:name', (req, res, next) => {
return res.render('speakers/detail', {
page: req.params.name,
});
});
return router;
};