Node.js express routers as middleware

Viewed 91

Today I've encountered problem which got me confused for a little while as I expected routers work little bit differently and can't quite comprehend what is going on here.

Suppose I want to define my routing using express.Router. I create two routers, one for authorization purposes and another one for general routing as so:

let authRouter = new express.Router()
let generalRouter = new express.Router()

Next I define several routes such as login and dashboard routes with post and get methods:

authRouter.get('login', loginHandler)
authRouter.post('login', loginHandler)
generalRouter.get('dashboard', landingHandler)

After that I append both of my routers to the actual express app object:

app.use(authRouter)
app.use(generalRouter)

But.. I also want my website to redefine the way 404 works, so I create an additional handler for this case, let it be notFoundHandler, and then I add app.use(notFoundHandler) in case a request hasn't been caught by one of the handlers. Finally, we have this handling order:

authRouter.get('login', loginHandler)
authRouter.post('login', loginHandler)
generalRouter.get('dashboard', landingHandler)
app.use(notFoundHandler)

Turns out, last route is never reached and doesn't apply newly created rule for 404 error. I tried moving this line into generalRouter's handle list and it worked perfectly. But as far as I know, middleware is processing requests in order you define them, so there has to be no trouble with putting handler out of handle of routers, since by writing code this way I say "when these routers didn't respond, respond with custom 404 error", but it didn't work out. So. Does app.use(Router) shadow the remaining middleware or is it something else?

UPD

Thing is, my second router stopped working as well, and it looks like going through all handlers in the first attached router shadows all the others with the same route parameter:

app.use(authRouter) // handles every route
app.use(generalRouter) // can't handle for some reason

even though app.use does not ultimately preserve usage of handler below unless we specify response behavior in it, generalRouter, which contains several possible user queries cannot be reached.

1 Answers

The problem was solved and it's pretty staightforward. app.use(handler) handles requests using specified middleware. When I put a router as middleware, I never called next in none of my function. One of possible solutions:

app.use(authRouter, (res,req,next) => next())
...
Related