Two routers mounted at same path do not isolate their middleware from each other

Using router.use seems to be documented to allow you to add middleware that will only be called for routes added to that router, but that does not seem to be working for me. The issue seems to be because I’m mounting several routers at the same path. The decision for whether a middleware is run seems to be based on the path, not the router. This was confusing.

The use case here is that my application has several modules that are mounted under the same location, as the URLs for these don’t always follow a common prefix. There’s common middleware that is used on most, but not all, endpoints. I was attempting to refactor the application to use an express.Router for each module, with each router being able to .use whatever middleware is common to all of its routes.

The result has been that the same middleware is called multiple times, because several routers are all using it. They should be separated, if Router worked as described. Another case is that one module used a middleware to require auth on all of the endpoints in its router, but that spilled over to any other routers used after that one.

Is this intended behavior? Is there a workaround?

Here is a Gist demonstrating the issue: https://gist.github.com/mjm/497a23f68826f8ca473b

Author: Fantashit

1 thought on “Two routers mounted at same path do not isolate their middleware from each other

  1. Just want to leave my 👍 here. Let me know if there’s something I’m doing wrong, but my use case is:

    1. I have two routers, one uses some authorization middleware and the other does not require authorization
    2. Both routers are mounted on the same path, and they might be responsible for handling different methods on the same endpoint

    In this scenario, I’m seeing that the authorization middleware is being applied to the route/methods being handled by the second router as well. To be more specific, in the following chunk of code, authorization is being applied to the routes in openRouter as well:

    var authRouter = express.Router()
    authRouter.use(authHandler)
    var openRouter = express.Router()
    
    authRouter.route('/applications/:template')
      .get(this.cluster.getAllApplications.bind(this.cluster))
    openRouter.route('/applications/:template')
      .post(this.cluster.createApplication.bind(this.cluster))
    
    app.use('/', openRouter)
    app.use('/', authRouter)
    

    Any thoughts on this?

Comments are closed.