Introduction
Express middlewares are functions that sit between the request and response cycle. These functions have access to the request and response objects and can intercept and change these objects. These middlewares are functions that can run codes, make changes to the request-response cycle
Why use express middlewares
- Security: express middlewares are used to improve the security of an application. This makes sure that only authorized users can access a particular resource on the application
- Improved functionality: express middlewares improve and extend the functionality of the application by adding
extra features needed in the application. example
express.json()
middleware helps the application parse JSON data. - Error handling: custom error handling middleware makes error handling better and more efficient throughout the application. By defining custom error-handling middleware, you can intercept and process errors from any route, logging or formatting them consistently for all routes.
- Code organization and reusability: functionalities like error handling, authentication, and logging can be separated into individual functions. This separation leads to cleaner, more maintainable code since each middleware has a specific purpose and can be reused across multiple routes.
Types of middlewares and how to use them
Global middleware / application-level middleware
This middleware exists on the application level. This makes it available to all routes. It is bound to the app
instance
using app.use()
.
const express = require("express")
const app = express()
app.use(logMethod)
app.get("/", (req, res) => {
res.send("Hello world");
});
function logMethod(req, res, next) {
console.log(req.method);
next()
}
app.listen(3000, () => console.log(`server started on 3000`));
This is a basic express server setup. The logMethod
function is the middleware which is used as a global middleware
using the app.use(logMethod)
. The logMethod
function has three parameters req
which is the request object, res
this is the response object and next
is a function that calls the next middleware to run.
The logMethod
middleware is a very basic middleware that logs the request method to the console. It is important to
note
that without the next()
function the next middleware would not run.
Route-specific middleware
This type of middleware is specific only to the route that uses it, unlike global middleware which is available to all the routes in the application. This type of middleware is commonly used as an authentication guard to protect routes that only authenticated users can access.
const express = require("express")
const app = express()
app.get("/user_details", checkAuth, (req, res) => {
res.send("This is the user's details page");
});
app.get("/about", (req, res) => {
res.send("This is an about page")
})
function checkAuth(req, res, next) {
if (req.query.authenticated === 'true') {
next()
} else {
res.status(401).send("Not authorized");
}
}
app.listen(3000, () => console.log(`server started on 3000`));
We have two routes, a protected route and a public route. The protected route is guarded with the checkAuth
middleware. This middleware checks if the user is authenticated, for the sake of this tutorial we will be using a basic
authentication logic, this logic checks if the authenticated query
parameter (http://localhost:3000/user_details?authenticated=true
) is set to true
if not it sends the user out with
the 401
HTTP code.
Built-in middleware
These are middlewares that come with the express package. They are built into the express package, so there is no need
to write custom functions or install additional packages to use these middlewares They help extend the functionality of
the express.js package and make performing common tasks easier. Built-in middlewares are mostly set as global
middlewares using the app.use()
const express = require("express")
const app = express()
app.use(express.json())
app.use(express.urlencoded({extended: false}));
app.get("/about", (req, res) => {
console.log(req.body)
res.send("This is an about page")
})
app.listen(3000, () => console.log(`server started on 3000`));
express.json()
is a middleware that parses incoming requests with JSON payloads. Without this middleware, thereq.body
object will be empty or undefined. This middleware accepts an object as an argument to further configure the behaviour to suit your use case.express.urlencoded()
is a middleware that handles incoming requests with urlencoded payload. This populates thereq.body
object with the parsed data. This middleware also accepts an object as an argument to further configure the behaviour to suit your use case.
Error-handling middleware
This middleware is used to make error handling better. For a middleware to be regarded as an error handling middleware,
it must take four arguments (err, req, res, next)
. The new argument here that makes it different from other types of
middleware is the err
argument. This argument contains details about the error.
const express = require("express")
const app = express()
app.get("/about", (req, res, next) => {
const err = new Error("Something went wrong")
next(err)
})
app.use(errorHandler);
function errorHandler(err, req, res, next) {
if (err) {
console.log(err.message)
res.status(400).send(err);
}
}
app.listen(3000, () => console.log(`server started on 3000`));
The errorHandler
middleware takes four arguments (err, req, res, next)
, we check if there is any error on the err
parameter then log the error message to the console and send the error to the client.
Notice that the GET
route has a third argument of next
this is because route actions are also middleware and
the next()
function calls the next middleware which is the errorHandler
also the app.use(errorHandler)
is called after the GET
route this is because middlewares are executed in the order
by which they were called. It is also important to make sure that the endpoint runs before the middleware to ensure
proper error handling in this case.
Third party middlewares
These are middlewares used to extend express application functionality to suit your use case. To use these middlewares, the package needs to be installed with node package manager (NPM) or yarn. Examples of third-party middleware are.
Cors():
This package is used to handle cross-origin resource sharing (CORS). With this package origins that can access resources within the express server can be managed.Multer:
This is similar to built-inexpress.json()
andexpress.urlencoded
the difference is this package parses formdata, this makes it possible to upload files in an express server.Body-parser:
Body parser transforms incoming data in different formats like JSON, URL-encoded form data, raw text, or other formats into readable format making it accessible viareq.body
object. This middleware is very similar to built-inexpress.json()
andexpress.urlencoded
. This middleware transforms more content types.
Conclusion
In this tutorial, we looked at express middleware, a very important feature in the Express.js framework. Middlewares add extra functionalities that make managing important features like authentication, parsing data in different and cross-origin resource sharing (CORS) easier. If you're a beginner looking for more information about the Express.js framework, head to the official documentation. HAPPY CODING!