Using Express Middleware
Tags: webdev, programming, javascript, beginners
Published: 2021-01-24 22:02:19

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Middleware functions are functions that have access to the request and response objects, and the next function for call the next middleware.

In this article, we’ll look at what Express middleware does and how we can use them.

Characteristics of Middleware
=============================

Middleware functions can run any code, make changes to the request and response object, end the request-response cycle, and call the next middleware in the stack.

Application-Level Middleware
============================

We can run middleware that are used when any routes are called by passing it to the `app.use` method as a callback.

If we want to a middleware function to be called only when a request of one request method is called, then we can pass it to the `app.METHOD` method as a callback. Where `METHOD` is `get` , `post` , `put` , `delete` , etc.

For example, we can write a middleware function and pass it into `app.use` to log the request method of a request as follows:

```
const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use((req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));
```

Then we should get `GET` logged when we make a GET request to `/` .

We can restrict the middleware function to be run only on GET requests and to the path `/` by writing:

```
const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.post('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));
```

Then we only see `GET` logged when we make GET requests to the `/` path.

Running a Series of Middleware Functions
========================================

We can use the `next` method to call the next middleware function in the series, so we can use it to chain middleware function calls together.

For example, if we have:

```
const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
);

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));
```

Then we see:

```
middleware 1 called  
middleware 2 called
```

from the `console.log` output of each middleware.

If we send a response in our middleware, then the next one won’t get called. For example, if we have:

```
const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/',  
  (req, res, next) => {  
    next()  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/',  (req, res, next) => {  
  res.end();  
})

app.listen(3000, () => console.log('server started'));
```

Then we get the output ‘Second middleware’ when we make a request to `/` .

Our route handler in:

```
app.get('/', function (req, res, next) {  
  res.end();  
})
```

wasn’t called.

We can call `next` as follows:

```
next('route');
```

to go straight to our route handler, bypassing the other middleware functions down the line.

For example, if we have:

```
const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.listen(3000, () => console.log('server started'));
```

Then when we make a request to `/0` , then we get `0` . Otherwise, we get ‘Second Middleware’ outputted.

Router Level Middleware
=======================

Router level middleware works the same way as app-level middleware, but they’re bound to the instance of the `express.Router()` instead of the `express` instance.

For example, we can use it as follows:

```
const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use((req, res, next) => {  
  req.requestTime = new Date();  
  next();  
})

router.get('/', (req, res, next) => {  
  res.json(req.requestTime);  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));
```

Then when we make a request to the `/` route we get back the timestamp as the output.

Chaining middlewares and skipping routes work the same way as app-level middleware. For example, we can write the following to chain middlewares as follows:

```
const express = require('express')  
const app = express()  
const router = express.Router();

app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
)

router.get('/', (req, res, next) => {  
  res.json();  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));
```

Then we see:

```
middleware 1 called  
middleware 2 called
```

from the `console.log` output of each route middleware.

We can use `next('route')` to skip to the route as follows:

```
const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

router.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.use('/', router);
app.listen(3000, () => console.log('server started'));
```

Then when we make a request to `/0` , then we get `0` . Otherwise, we get ‘Second Middleware’ outputted.

Conclusion
==========

Using Express middlewares is simple. We can either pass them into `app.use` to make the middleware run for all request methods, or `app.METHOD` to make them run for the given method.

We can call `next` to call the next middleware, and call `next('route')` to call the route handler directly from a middleware.

Everything applies to both route and app-level middleware, except that they bind to the `express.Router()` and `express()` respectively.