May 23, 2024

ExpressJS Middleware Functions

If you have started reading about ExpressJS you would have definitely come across a term called middleware in ExpressJS. You might have thought what is this new complexity in ExpressJS but fear not middleware is just a function with access to request and response objects and it has logic like any other function.

Middleware in ExpressJS

Middleware functions are the functions that take request object, response object and next function as parameters in the application's request-response cycle. The next() function, when invoked with in a middleware, moves the execution to the next middleware.

Using middleware functions you can do the following tasks-

  1. Write any logic which will be executed.
  2. Modify the request and response objects like parsing request body, setting response header.
  3. Call the next middleware function by invoking next() function.
  4. End the request-response cycle by calling response.send()

Let's try to understand middleware function using the following code-

const express = require('express');
const app = express();
const port = 3000;
app.get('/', function(req, res, next){
    console.log('In a middleware');
    next();
})
app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

In the above code app.get() is the HTTP method.

With in the app.get() method middleware function is the given code.

function(req, res, next){
    console.log('In a middleware');
    next();
}

If the current middleware function does not end the request-response cycle be sending a response back, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.

If you run the above example and access the URL http://localhost:3000/ you will get a message on the console 'In a middleware' but the browser won't show you any result as no response is sent back from the server.

Example with middleware functions

Here is another example with three middleware functions. Note the use of next() in the first two middleware functions so that control is passed from first middleware to second. From the third middleware function a response is sent back which also stops the request-response cycle.

const express = require('express');

const app = express();
const port = 3000;

// specific to root path
app.use('/', function(req, res, next){
    console.log('Logging a request for root path');
    next();
})

// middleware applicable to all requests (any path)
app.use(function(req, res, next){
    console.log('In middleware-2');
    next();
})

app.get('/', function(req, res){
    console.log('In middleware-3');
    res.send('<h3>Hello from ExpressJS</h3>');
})

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

On running this example and accessing the URL http://localhost:3000/ you'll see the following messages in the given order.

Logging a request for root path

In middleware-2

In middleware-3

Browser also displays the response sent from the server.

This chaining of middleware functions can be described using the following image.

ExpressJS Middleware Functions

In the above code you can remove the next() function from the first middleware.

app.use('/', function(req, res, next){
    console.log('Logging a request for root path');
    //next();
})

After restarting the server if you access the URL http://localhost:3000/ you won't get any response now as code execution is stuck at the first middleware.

Types of middleware

In an Express application you can use the following types of middlewares.

  1. Application-level middleware- You can bind application-level middleware to an app object (which you get by calling express() function) 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. We have already seen examples of application-level middleware.
  2. Router-level middleware- Router-level middleware works in the same way as application-level middleware, difference being that it is bound to an instance of express.Router(). You can bind the router-level middleware by using the router.use() and router.METHOD() functions. Read more about express.Router() in this post- express.Router() Function With Examples
  3. Error-handling middleware- You can define error-handling middleware functions too. In that case function takes four arguments instead of three, specifically with the signature (err, req, res, next).
  4. Built-in middleware- Express also has built-in middleware functions like-
    1. express.static- Serves static assets such as HTML files, images, and so on.
    2. express.json- Parses incoming requests with JSON payloads.
    3. express.urlencoded- Parses incoming requests with URL-encoded payloads.
  5. Third-party middleware- You can also use third-party middleware to add functionality to Express apps. For example body-parser which parses HTTP request body, morgan which is a HTTP request logger.

That's all for the topic ExpressJS Middleware Functions. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment