DEV Community 👩‍💻👨‍💻

Pratham Sharma
Pratham Sharma

Posted on

Guide To Express Middlewares

A basic definition

Express middlewares are the functions that have access to the request, response and next function in applications request response cycle. The next function calls the next middleware that is succeding the current middleware.

Let's simplify the above statement a bit. So a express middleware is basically a function that has req,res and next as a parameters. For example,

const express = require('express')
const app = express()

function logger(req, res, next) {
  console.log("I am a middleware and I log the text");
  next();
}
app.use(logger)
app.get('/', (req,res)=>{
 res.send("Hellow World!!")
})
app.listen(3000)
Enter fullscreen mode Exit fullscreen mode

Now here I have a logger function which is a middleware. Yup that's how simple a middleware can be. Here the logger function has one thing which other functions don't have. You always have to call next at the end of the middleware. This basically invokes the next or succeding middleware.
For example

function logger1(req, res, next) {
  console.log("I am first");
  next();
}

function logger2(req, res, next) {
  console.log("I am second");
  next();
}

app.use(logger1);
app.use(logger2);
Enter fullscreen mode Exit fullscreen mode

here logger1 is the first middleware and the logger2 is next or succeding middleware.This of course depends on the which function is loaded first in app.use(). So now whenever express calls a callback then these 2 middlewares will do a console.log() before running that callback. If I was to load the logger2 before logger1 then logger2 will console log before logger1.

For example if I add this to last line of previous code then.

app.get("/", (req, res) => {
  res.send("Hellow World!!");
  console.log("I am a callback");
});
// output in the console will be
// I am first
// I am second
// I am a callback
Enter fullscreen mode Exit fullscreen mode

The next function could be named anything else either but by convention it is always named next. So to avoid any confusion we continue calling it next. Also remeber if you don't call next() at the end of the middleware then the middleware will never go to the next or succeding middleware. This means the request will left hanging and will never proceed

Example : Using a middleware to get a object from database

In my app I use following middleware to get a snippet by a certain id provided in a request.

This can give you a gist of where to use a middleware.

function getSnippetById(req, res, next) {
  let snippet;
  try {
    // here Snippets is mongoose schema.
    snippet = await Snippets.findById(req.params.id);
    if (snippet == null) {
      return res.status(404).json({
        message: "question does not exist",
      });
    }
  } catch (err) {
    res.status(401).json({ message: err.message });
  }

  res.snippet = snippet;
  next();
}
Enter fullscreen mode Exit fullscreen mode

In this middleware I simply check for the snippet in database if it does not exists we return a error other wise I attach the snippet with give header. Now here snippet keyword is a custom header that I provide which I can access in the callback further.
For example if I do

app.get("/:id", getSnippetById, (req, res) => {
  res.status(200).json(res.snippet);
});
Enter fullscreen mode Exit fullscreen mode

now here I didn't use app.use instead I called the middleware directly inside the get request. This is useful because app.use will call the function getSnippetById beforeevery request which is not what we want. So instead we call it only for some function such as when we want to delete, update or get a object(in this case snippet) by a certain id.

I should also mention something called as a error-handling middleware which depends on same concept. You can see more about error handling middleware here.

Conclusion

So we went over how the middlewares are called, what is next function and what happens when we don't call it and also we went over a real world example of a middleware too. To read a better and a detailed explanation checkout the express docs on writing a middleware and also on using a middleware

Top comments (0)

Need a better mental model for async/await?

Check out this classic DEV post on the subject.

⭐️🎀 JavaScript Visualized: Promises & Async/Await

async await