DEV Community

loading...

Express middlewares and Higher Order Functions

Tirtha Guha
javascript, ux, nodejs, react, backbonejs, marionettejs, npm, devops, docker, aws
Updated on ・2 min read

Like I said in the first post of the series, Express is all about middlewares.
So, here's the problem statement

Problem Statement

Can we create a middleware out of any function, so that developers don't have to worry about the tricky syntax and testing of middlewares

Well, the hardest part is over, defining the problem. Let's get our hands dirty now.

The generic syntax of a middleware is

//generic express middleware syntax
const middleware = (req, res, next) => {
  // EXECUTION LOGIC
  next(); // This is where the control leaves this middleware and moves to next item in the queue, which could be another middleware, or the final controller etc
}
Enter fullscreen mode Exit fullscreen mode

Our intention is make it work in a way, that we should be able to inject the EXECUTION LOGIC dynamically.

For this, we slightly move away from OOPS of JS and take help of a functional programming concept called Higher Order Function.

How does it help, you ask? Well, we're going to create a function, that returns a middleware. and through that function, we're going to inject the execution logic.

We're going to create a file, withMiddleware.js

//withMiddleware.js

//Higher Order Function
const withMiddleware = (func) => {
  return (req, res, next) => {
    func(); //func has the EXECUTION LOGIC
    next();
  }    
}

module.export = withMiddleware;

Enter fullscreen mode Exit fullscreen mode

Let's see how we can make this work for us.

const withMiddleware = require('./withMiddleware');

const funcOne = () => {
  //YOUR BUSINESS LOGIC
}

const funcTwo = () => {
  //YOUR ANOTHER BUSINESS LOGIC
}

const middlewareOne = withMiddleware(funcOne);
const middlewareTwo = withMiddleware(funcTwo);

//use this middlewares in a standard way.
app.get("/path", middlewareOne, middlewareTwo, (req, res)=>{
  //further execution, if any
  res.send({});
})
Enter fullscreen mode Exit fullscreen mode

The Magic ends here for now, but there are a few problems yet to be solved for this. In the next post we're going to take this a little higher and address the following

  1. How will we handle the async middlewares?
  2. What if I'm writing auth or validation middlewares, that needs access to the request object?
  3. Passing data between middlewares? Although we solved it in the first post, see the PS: section, but how can we make it work effortlessly
  4. Logging. The generic activities of the middlewares needs to be logged. Like, in case of async middleware, that fetches data over another API, or fetches data from a DB, the time taken for the async operation needs to be logged.

Discussion (0)