Using middleware
Express is a lightweight routing and middleware web framework. An Express application is essentially a series of middleware function calls executed during the request-response cycle.
Middleware functions are functions that have access to:
- The request object (
req) - The response object (
res) - The next middleware function in the application’s request-response cycle, commonly named
next
Middleware functions can perform the following tasks:
- Execute any code
- Modify the request and response objects
- End the request-response cycle
- Pass control to the next middleware function
If a middleware function does not end the request-response cycle, it must call next(). Otherwise, the request will remain pending.
Express applications can use the following types of middleware:
- Application-level middleware
- Router-level middleware
- Error-handling middleware
- Built-in middleware
- Third-party middleware
You can load middleware functions with an optional mount path. Multiple middleware functions can also be grouped together to create a middleware sub-stack at a specific mount point.
Application-level middleware
Application-level middleware is bound to an instance of the app object using:
app.use()app.METHOD()
where METHOD is the lowercase HTTP method such as get, post, put, or delete.
Middleware without a mount path
The following middleware runs for every incoming request:
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('Time:', Date.now())
next()
})
Middleware mounted on a specific path
The following middleware runs for all request types on /user/:id:
app.use('/user/:id', (req, res, next) => {
console.log('Request Type:', req.method)
next()
})
Route handler example
This route handles GET requests to /user/:id:
app.get('/user/:id', (req, res) => {
res.send('USER')
})
Multiple middleware functions
Middleware functions can be chained together to form a middleware sub-stack:
app.use(
'/user/:id',
(req, res, next) => {
console.log('Request URL:', req.originalUrl)
next()
},
(req, res, next) => {
console.log('Request Type:', req.method)
next()
}
)
Route middleware sub-stack
The following example demonstrates multiple middleware handlers for the same route:
app.get(
'/user/:id',
(req, res, next) => {
console.log('ID:', req.params.id)
next()
},
(req, res) => {
res.send('User Info')
}
)
The middleware above ends the request-response cycle using
res.send(). Any matching routes defined after this will not execute unlessnext('route')is used.
Skipping to the next route
Call next('route') to skip the remaining middleware functions for the current route.
next('route')works only in middleware functions loaded usingapp.METHOD()orrouter.METHOD().
app.get(
'/user/:id',
(req, res, next) => {
if (req.params.id === '0') {
next('route')
} else {
next()
}
},
(req, res) => {
res.send('regular')
}
)
app.get('/user/:id', (req, res) => {
res.send('special')
})
Reusable middleware arrays
Middleware functions can also be grouped into arrays for better reusability:
function logOriginalUrl (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}
function logMethod (req, res, next) {
console.log('Request Type:', req.method)
next()
}
const logStuff = [logOriginalUrl, logMethod]
app.get('/user/:id', logStuff, (req, res) => {
res.send('User Info')
})
Router-level middleware
Router-level middleware works the same way as application-level middleware, except it is bound to an instance of express.Router().
const router = express.Router()
Load router-level middleware using:
router.use()router.METHOD()
The following example demonstrates router-level middleware:
const express = require('express')
const app = express()
const router = express.Router()
// Runs for every request handled by this router
router.use((req, res, next) => {
console.log('Time:', Date.now())
next()
})
// Middleware sub-stack
router.use(
'/user/:id',
(req, res, next) => {
console.log('Request URL:', req.originalUrl)
next()
},
(req, res, next) => {
console.log('Request Type:', req.method)
next()
}
)
// Route-specific middleware
router.get(
'/user/:id',
(req, res, next) => {
if (req.params.id === '0') {
next('route')
} else {
next()
}
},
(req, res) => {
res.render('regular')
}
)
// Special route handler
router.get('/user/:id', (req, res) => {
console.log(req.params.id)
res.render('special')
})
// Mount router
app.use('/', router)
Skipping out of a router
Use next('router') to exit the current router instance and pass control back to the main application.
const express = require('express')
const app = express()
const router = express.Router()
// Router guard middleware
router.use((req, res, next) => {
if (!req.headers['x-auth']) {
return next('router')
}
next()
})
router.get('/user/:id', (req, res) => {
res.send('hello, user!')
})
// Fallback handler
app.use('/admin', router, (req, res) => {
res.sendStatus(401)
})
Error-handling middleware
Error-handling middleware always requires four arguments:
(err, req, res, next)
Even if you do not use next, you must include it to ensure Express recognizes the function as error-handling middleware.
Example:
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})
For more information, see: Error handling
Built-in middleware
Starting from Express 4.x, Express no longer depends on Connect. Middleware previously bundled with Express is now maintained in separate modules.
Express includes the following built-in middleware functions:
-
express.static
Serves static assets such as HTML files, images, CSS files, and JavaScript files. -
express.json
Parses incoming requests with JSON payloads. -
express.urlencoded
Parses incoming requests with URL-encoded payloads.
Third-party middleware
Third-party middleware can be used to add additional functionality to Express applications.
Install the required package using npm and load it either at the application level or router level.
The following example demonstrates the cookie-parser middleware:
npm install cookie-parser
const express = require('express')
const cookieParser = require('cookie-parser')
const app = express()
// Load cookie-parsing middleware
app.use(cookieParser())
For more commonly used middleware packages, see: Third-party middleware
Edit this page