Search code examples
javascriptexpressmiddleware

How to get name of next middleware function in Express.JS


I'm trying to get the names of middleware functions in a particular request route. Let's say I have the following code implemented:

const authorizeRoute = (req,res,next) => {
  let nextFunctionName = SomeFunctionToRetrieveTheNameOfTheNextMiddlewareToBeCalled()
  if (isUserAuthorized(req.user.id, nextFunctionName)) next()
}

app.use(authorizeRoute)
app.get("/users", controller.getUsers)
app.get("/users/:id/posts", controller.getUserPosts)

I want the authorizeRoute middleware to be able to get the name of the middleware function to be called next in the stack.

Like, if there's a GET request to "/users", I want the nextFunctionName to have the value of "getUsers" or "controller.getUsers" or something similar. Or GET "/users/:id/posts" have the same nextFunctionName to be "getUserPosts" or something.

How will I do this?

I'm still new to Express and Node or even javascript. How would I go about doing this?

I know this is possible somehow because there's already a way to get the function name as a string in javascript.

someFunction.name // gives "someFunction" returned as a string

So I know it can be done. I just don't know, how.

P.S. I know there are alternate ways of accomplishing the desired effect, but my need for this is not exactly reflected in the above snippet, but I tried my best to have it showcased.


Solution

  • figured it out. I can't put the middleware to get the stack for a route using app.use but if the middleware is put among the handlers for the route, it will work.

    const SomeFunctionToRetrieveTheNameOfTheLastMiddleware(req) => {
      let stack = req.route.stack
      return stack[stack.length-1].name
    }
    
    const authorizeRoute = (req,res,next) => {
      let nextFunctionName = SomeFunctionToRetrieveTheNameOfTheLastMiddleware(req)
      if (isUserAuthorized(req.user.id, nextFunctionName)) next()
    }
    
    app.get("/users", authorizeRoute, controller.getUsers)
    app.get("/users/:id/posts", authorizeRoute, controller.getUserPosts)
    

    I had the answer to the question in the question itself 😐