Middleware
From the Express docs…
A middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application.
- invoked before your final request handler is
- (between the raw request and the final intended route)
- called in order that they are added
What's That Mean?
Again, but with more details.
- middleware is just a function
- it's a function that has three parameters:
- a request object (usually
req
)
- a response object (usually
res
)
- and the next middleware function to be executed (conveniently called
next
)
"An Express application is essentially a stack of middleware which are executed serially."
Using Middleware
Middleware can be:
- application - executed for the entire application
- or router level - only executed for a specific path
You can use middleware simply by calling the aptly named:
Calling Next
Furthermore, if the current middleware doesn't end the request-response cycle, it should really remember to call next()
. What will happen if it doesn't? →
- a response will never be sent
- the request will be left hanging
- (nothing good)
Let's Build Some Hello World Middleware
Create middleware that always logs the word 'hello' for every request. →
app.use(function(req, res, next) {
console.log('hello');
next();
});
How About Some Useful Middleware, Please!
Create middleware that always logs the request's method and path. →
app.use(function(req, res, next) {
console.log(req.method, req.path);
next();
});
(also… let's play around with ordering. →)
One Last Custom Middleware
Does anyone remember a response header that identifies the type of server that's being run? →
Server:Apache/2.2.22 (Ubuntu)
How about we set our own Server
response header?
We can use res.set(headerName, headerValue)
.
app.use(function(req, res, next) {
res.set('Server', 'MY AMAZING SUPER COOL SERVER');
next();
});
About That…
Actually, most people try to suppress or remove that Server header. Why? →
Security through obscurity!
- maybe it's better if you don't reveal anything about your technology or infrastructure
- (what if there were known exploits for a specific version of the web server that you're running?)
All Together (If You Were Curious)
import express from 'express';
const app = express();
app.use(function(req, res, next) {
console.log(req.method, req.path);
next();
});
app.use(function(req, res, next) {
console.log('hello');
next();
});
app.use(function(req, res, next) {
res.set('Server', 'MY AMAZING SUPER COOL SERVER');
next();
});
app.get('/', function(req, res) {
res.send('We\'re done here');
});
app.listen(3000);
The Static File Middleware
What do you think the static file middleware does? How does it work in the request-response life cycle?→
- it checks the path in the incoming request
- tries to find if the file exists in the file system
- if it doesn't, it calls the next middleware (so if the path is not there, it'll drop through to your routes)
- more info in the docs
Using the Static File Middleware
How do we actually use the static file middleware? →
- (there's nothing to install, it's bundled with express)
- you only need to specify your public directory (but you could be courteous about it)
app.use(express.static('public'));
import path from 'path';
import url from 'url';
const basePath = path.dirname(url.fileURLToPath(import.meta.url));
const publicPath = path.resolve(basePath, "public");
app.use(express.static(publicPath));