Skip to main content

πŸ“¦ Middleware

  • Express Documentation
  • Middleware are functions that run right before your handlers run.
  • They can do things like augment the request, log, handle errors, authenticate, and pretty much anything else.
  • They look exactly like a handler with one difference. Because you can have a list of middleware, there needs to be a mechanism to move into the next middleware function when work is done in the current middleware.
    It looks like this:
const myMiddlware = (req, res, next) => {
// ... do my work, and when I done call next()
next();
};

This next function is exactly what it sounds like. It tells Express that we're done in the middleware and it's safe to proceed to whatever is next (more middleware or a handler). To apply the middleware to a route, you can do this:

app.get("/todo/:id", myMiddleware, my2ndMiddleware, handler);
// or
app.get("/todo/:id", [myMiddleware, my2ndMiddleware], handler);

Middleware will run in the order in which you passed them as arguments.

πŸ“‹ Example​

It's things you can add to Redux before you serialize it into state or not or whatever, right? It could be a dev tool.It can be a persistent state.It could be a thunk or something like that.

Use Cases​

  • Some use cases are like, maybe you wanna log the request.Yeah, that's perfect job for middleware.
  • You wanna see in your terminal every time someone hit your request.Yeah, that's very helpful for developments.So you know when a request came in, what the request was,how long it took, maybe you want to handle errors.
  • Logging and Monitoring:
    Middleware can log incoming requests, responses, and errors for monitoring and debugging purposes.
  • Authentication and Authorization:
    Middleware can handle user authentication (verifying user identity) and authorization (checking user permissions).
  • Request Parsing:
    Middleware can parse incoming request bodies (e.g., JSON, URL-encoded data) and make the data accessible in the request object.
  • Session Management:
    Middleware can manage user sessions, storing session data in cookies or server-side storage.
  • Error Handling:
    Middleware can catch and handle errors, sending appropriate responses to the client and logging the errors for further analysis.
  • CORS Handling:
    Middleware can set Cross-Origin Resource Sharing (CORS) headers to allow or restrict access to resources from different origins.
  • Static File Serving:
    Middleware can serve static files (e.g., HTML, CSS, JavaScript) from a specified directory.
  • Request Compression:
    Middleware can compress response bodies to reduce the amount of data transmitted over the network.
  • Rate Limiting:
    Middleware can limit the number of requests a client can make in a certain period, helping to prevent abuse and DoS attacks.
  • Data Validation:
    Middleware can validate incoming request data to ensure it meets certain criteria before processing.
  • Localization and Internationalization:
    Middleware can manage language settings and serve content in different languages based on user preferences or location.
  • Response Modification:
    Middleware can modify response objects before they are sent to the client, such as adding headers or modifying the response body.
  • Custom Middleware:
    Developers can create custom middleware to handle specific tasks unique to their applications.

πŸ“¦ Middleware Libraries​

So some really useful middleware that we're gonna use.One of them is called Morgan.

  • Morgan is a middleware that logs requests,that's literally all it does, and it's super useful.

    npm i morgan --save
    npm i --save-dev @types/morgan

open the src/server.ts file then import the morgan library and use it as a middleware. I have used the dev format, which is a predefined format that logs the request method, URL, status code, response time, and other details. You can also use other predefined formats like combined, common, short, and tiny, or define your custom format.

note

Remember, order matters.So we always put your middleware at the top,before all your other routes if you want the routes to come after the middleware.So middleware usually comes first;

import express from "express";
import router from "./router";
import morgan from "morgan";
const app = express();

app.use(morgan("dev"));

app.get("/", (req, res) => {
morgan;
res.status(200).send({
success: true,
message: "Welcome to the Node.js and Express API",
});
});

app.use("/api", router);

export default app;

When you hit the end point then server console this response.

GET /api/product/ 200 12.645 ms - 51

But if you use any logging products, a logger API,they would probably have an SDK that has a middleware that sits on your express that sends your logs to their servers.So, they can show you on a dashboard, data dog or something like that.

Do we have the options to say only want this middleware to intercept these routes?​

There's so many ways you can do that.You can do that on the code level where inside you just set the middleware to be global.And then inside the middleware, you specifically check against a list of routes that you specifically want to do and only run your code there.That's one way.
The other way is, you can do it on a configuration level where you only add the middleware to the routes that you want it to affect.So, for instance we added the middleware globally here but there's nothing stopping me from adding middleware here only for this.