express middleware
pre reqs
- We're going to assume you know the basics of Express
- Node latest LTS (v12.16.2)
- Postman
- Yarn
getting started
- Fork & Clone
-
$ git checkout -b develop
-
$ yarn
-
$ yarn setupenv
in a world...
...without middleware...
yarn run v1.22.0
$ yarn build && nodemon ./lib/index.js
$ rimraf ./lib && babel src -d lib
Successfully compiled 4 files with Babel.
[nodemon] 2.0.3
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node ./lib/index.js`
Application listening on port 3000
$ yarn dev
womp womp...
Phase 2???
Listen for Requests
Resolve the output
middleware functions
const genericMiddleware = (
req /* Request Object */,
res /* Response Object */,
next /* Next Callback */)
=> {
// do something
// then use the response object and end the chain
// OR
// call the next() callback to execute the next middleware.
}
our first middleware
// new file: ./src/server/middleware/simpleLogger.js
const simpleLogger = (req, res, next) => {
console.log(`Request Type: ${req.method} received at ${Date.now()}`);
next();
}
export default simpleLogger;
// ./src/server/index.js
import express from "express";
import simpleLogger from './middleware/simpleLogger'; // new!
const launchServer = (port) => {
const app = express();
app.use(simpleLogger); // new!
return app.listen(port, () => {
console.log(`Application listening on port ${port}`);
});
};
export default launchServer;
yay
$ yarn dev
yarn run v1.22.0
$ yarn build && nodemon ./lib/index.js
$ rimraf ./lib && babel src -d lib
Successfully compiled 6 files with Babel.
[nodemon] 2.0.3
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node ./lib/index.js`
Application listening on port 3000
Request Type: GET received at 1587070701458
application level middleware
- middleware bound to the "app" object returned by express();
- app.use (applies to all methods)
- app[method] applies to specific methods.
- app.get
- app.post
- app.patch
- app.put
- app.delete
|
|
|
application paths
for either app.use or app[method];
const launchServer = (port) => {
const app = express();
app.use(simpleLogger);
/* NEW STUFF! */
app.get('/hello-world', (req, res) => {
res.send('Hello World!')
})
/* END NEW STUFF */
return app.listen(port, () => {
console.log(`Application listening on port ${port}`);
});
};
export default launchServer;
localhost:3000/hello-world
bit basic?
types of middleware
- application middleware - for the entire app
- router middleware - for a specific Router instance (advanced Express, but basically the same as application middleware)
- Built-in middleware (by Express itself)
- Error-Handling Middleware (a special case)
- Third Party Middleware (one of the above, but written as an npm package)
error handling middleware
for when things go a little bit oopsy-doodle
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
})
Note that this takes FOUR arguments, not three, with the first argument being "err"
Also, you define error-handling middleware after all your other app.use() and other route calls.
throwing an error
app.get('/', function (req, res, next) {
fs.readFile('/file-does-not-exist', function (err, data) {
if (err) {
next(err) // Pass errors to Express.
} else {
res.send(data)
}
})
})
If next is passed *ANY* parameter other than the string "route", Express will regard the current request as being an error, and will skip any remaining non-error handling routing and middleware functions.
third party middlewares
- body-parser - parses HTTP request body
- cors - allows cross-origin-resource sharing
- morgan - HTTP request logger
- passport - Authentication/Authorisation library
- session - establish server-based sessions
- timeout - set a timeout period for http request processing
advanced middleware
paths can have multiple routes
// handler for the /user/:id path, which prints the user ID to the console
app.get('/user/:id', function (req, res, next) {
console.log('ID:', req.params.id)
next()
})
// handler for the /user/:id path, which prints the user ID to the browser
app.get('/user/:id', function (req, res, next) {
res.send(`User is ${req.params.id}`)
})
advanced middleware
Routes can have more than one middleware
// handler for the /user/:id path, which prints the user ID to the console
app.get(
"/user/:id",
(req, res, next) => {
console.log("ID:", req.params.id);
if (["bozo", "pennywise", "krusty", "ronald"].includes(req.params.id)) {
console.warn("CLOWN DETECTED");
next(); // go to the next function in this function chain;
} else {
next("route"); // go to the next matching route, skip the other functions;
}
},
(req, res, next) => {
res.send(`Hey! I thought I told you clowns to get out of here!`);
}
);
// handler for the /user/:id path, which prints the user ID to the browser
app.get("/user/:id", (req, res, next) => {
res.send(`User is ${req.params.id}`);
});
questions?
Express Middleware
By brianboyko
Express Middleware
- 566