skip to Main Content

I would like to have different routes under an /api path with different middleware handlers. Specifically different API routes should allow different ways of authenticating.

I thought I could nest different API routes under two different Routers with different middleware:

const express = require("express");

const app = express();
const port = 4000;

const one = express.Router();
one.use((req, res, next) => {
  console.log("one");
  next();
});
one.get("/api/one", (req, res) => {
  console.log("/api/one");
  res.send("one");
});

// ---

const two = express.Router();
two.use((req, res, next) => {
  console.log("two");
  next();
});
two.get("/api/two", (req, res) => {
  console.log("/api/two");
  res.send("two");
});

// ---

app.get("/", (req, res) => {
  res.send("Hello World!");
});
app.use(one);
app.use(two);

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

I would expect that one would get logged when navigating to /api/one and two gets logged when navigating to /api/two, however both middlewares get run when navigating to /api/two:

Example app listening on port 4000
one
/api/one
one
two
/api/two

Is there a way to achieve what I’m looking for without listing the different middleware for each individual API route?

2

Answers


  1. The best I can think of here is to use different path prefixes, the router middleware will only get triggered for the specific route prefix.

    const express = require("express");
    
    const app = express();
    const port = 4000;
    
    const one = express.Router();
    one.use((req, res, next) => {
      console.log("one");
      next();
    });
    one.get("/one", (req, res) => {
      console.log("/api/one");
      res.send("one");
    });
    
    const two = express.Router();
    two.use((req, res, next) => {
      console.log("two");
      next();
    });
    two.get("/two", (req, res) => {
      console.log("/api/two");
      res.send("two");
    });
    
    app.get("/", (req, res) => {
      res.send("Hello World!");
    });
    
    // Different prefix
    app.use("/api1", one);
    app.use("/api2", two);
    
    app.listen(port, () => {
      console.log(`Example app listening on port ${port}`);
    });
    
    Login or Signup to reply.
  2. Yes you can do this. Express allows multiple routers and you can mount them at different paths. A simple example would be:

    RouterOne.cjs

    const express = require("express");
    const one = express.Router();
    one.get("/", (req, res) => {
      console.log("/api/one");
      res.send("one");
    });
    module.exports = one;
    

    RouterTwo.cjs

    const express = require("express");
    const two = express.Router();
    two.get("/", (req, res) => {
      console.log("/api/two");
      res.send("two");
    });
    module.exports = two;
    

    app.js

    const express = require("express");
    const one = require("./RouterOne.cjs");
    const two = require("./RouterTwo.cjs");
    function authOne (req, res, next) {
        console.log('Middleware: authOne');
        next();
    }
    function authTwo (req, res, next) {
        console.log('Middleware: authTwo');
        next();
    }
    app.use('/api/one', authOne, one);
    app.use('/api/two', authTwo, two);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search