If you are already working on some Node.js projects using Express.js framework, you might have heard of the term Middleware many times. In this article we will cover What is a middleware in Node.js and how to use it.
A middleware is basically a function that will the receive the Request and Response objects, just like your route Handlers do. As a third argument you have another function which you should call once your middleware code completed executing. This means you can wait for asynchronous database or network operations to finish before proceeding to the next step.
Few points to remember about middleware functions are:
- It does something in the middle of request and response cycle.
- Middleware has access to the request and response objects.
- It has access to next function of request-response life cycle
Middleware functions can perform the following tasks:
- Execute any code.
- Make changes to the request and the response objects.
- End the request-response cycle.
- Call the next middleware in the stack.
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next function. Otherwise, the request will be left hanging.
What is the work of next() in a middleware function?
Middleware functions are just some functions that accepts the request and response objects and do some operation with them. As a third argument you have another function which you should call once your middleware code completed just like we have one in case of callback functions. So the work of the next() is to pass control to the next middleware function.
Let us see an example of a Middleware function:
In the above code, we are using express framework with Node.js. We have defined a custom middleware named as logger that logs the request url, the request method and the request date. It is an example of a Logger middleware, which helps us in logging different stuffs while doing Asynchronous programming with Node.js.
Types of Middlewares in Express.js
An Express application can use the following types of middleware:
- Application-level middleware
- Router-level middleware
- Error-handling middleware
- Built-in middleware
- Third-party middleware
We will discuss about them one by one.
1. Application-level middleware
Bind application-level middleware to an instance of the app object by using the app.use() and app.METHOD() functions, where METHOD is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.Router-level middleware
2. Router-level middleware
Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of express.Router().
3. Error-handling middleware
We define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature
(err, req, res, next)).
4. Built-in middleware
Express has the following built-in middleware functions:
- express.static serves static assets such as HTML files, images, and so on.
- express.json parses incoming requests with JSON payloads. NOTE: Available with Express 4.16.0+
- express.urlencoded parses incoming requests with URL-encoded payloads. NOTE: Available with Express 4.16.0+
5. Third-party middleware
You can use third-party middleware to add functionality to Express apps. Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level.
Node.js middleware functions can be used in various ways. Let us discuss them one by one.
For every request to the server
The above middleware is called for every request on the server. So after every request, we will get the following message in the console:
A new request received at 146726656565
Restrict it to a specific route
To restrict it to a specific route (and all its subroutes), provide that route as the first argument of app.use(). For Example:
In the above code, whenever you request any subroute of ‘/todo’, only then it will log the time unlike the first example where it was logging each and every requests.
You can chain middlewares, either in the middlewares array shown in the last example above, or by using multiple app.use calls:
The middleware functions execute in the order of their use calls or their order in the array. Also, they will receive the Request object from previous middleware functions, so they can depend on each others functionality, like your custom middleware being inserted after bodyParser and thereby being able to use the parsed body.