'Grouping routes in Express

We can group our routes like this in Laravel:

Route::group("admin", ["middleware" => ["isAdmin"]], function () {

     Route::get("/", "AdminController@index");
     Route::post("/post", ["middleware" => "csrf", "uses" => "AdminController@index");

});

Basically, all the routes defined in admin group gets the isAdmin middleware and group name automatically. For example, post endpoint listens to admin/post not /post

Is there any way to do the same thing with Express? It would be awesome because my Laravel routes used to be so clean, whereas my Express routes are a bit messy/duplicated.

This is my routes.js on Express at the moment.

app.get("/admin", [passportConfig.isAuthenticated, passportConfig.isAdmin], AdminController.index);
app.post("/admin", [passportConfig.isAuthenticated, passportConfig.isAdmin], AdminController.postIndex);

Thank you.



Solution 1:[1]

Since express 4 you can define and compose routers

const app = require('express');
const adminRouter = app.Router();

adminRouter.use(isAdmin);
adminRouter.get('/', admin.index); /* will resolve to /admin */
adminRouter.post('/post', csrf, admin.index); /* will resolve to /admin/post */

app.use('/admin', adminRouter); 

Hope that helps!

Solution 2:[2]

Just use before of every group you want to do:

app.use('/admin', AdminMiddleware);
app.get('/admin/route1', ... 
app.get('/admin/route2', ... 

app.use('/user', UserMiddleware);
app.get('/user/route1', ...
app.get('/user/route2', ...

Solution 3:[3]

var app = require('express');
require('express-group-routes');

app.group("/api/v1", (router) => {
    router.get("/login", loginController.store); // /api/v1/login 
});

In case you don't want to add a prefix but still need to group certain routes you can leave the first parameter and go straight for the function:

 var app = require('express');
require('express-group-routes');

app.group((router) => {
    router.use(middleware);
});

Solution 4:[4]

You can use app.use() - https://expressjs.com/en/guide/using-middleware.html#middleware.application

app.use("/admin",[passportConfig.isAuthenticated, passportConfig.isAdmin],AdminController)


// AdminController:
var express = require('express');
var router = express.Router();
router.get('/', AdminController.index);
// etc...
module.exports = router

https://expressjs.com/en/guide/routing.html#express-router

Solution 5:[5]

I found some better solution you can follow this method it's working good

Route file route/user.js

var express = require('express')
var router = express.Router()
const authMiddleware = require('../middleware/auth')

express.application.prefix = express.Router.prefix = function(path, middleware, configure) {
    configure(router);
    this.use(path, middleware, router);
    return router;
}


router.prefix('/user', authMiddleware, async function (user) {
    user.route('/details').get(function(req, res) {
        res.status(201).send('Hello this is my personal details')
    }); //also you can use controller method if you have any
});

module.exports = router //make sure you have to import/use this route in main/server js

Solution 6:[6]

I just wrote this module to solve your problem: https://github.com/benjamin658/express-inject-middleware

You can group your middlewares as an array and pass it to the express-inject-middleware...

For example:

import express from 'express';
import { injectMiddleware } from 'express-inject-middleware';

const app = express();

const authMiddleware = (req, res, next) => {
  // some auth logic...
};

const fooMiddleware = (req, res, next) => {
  // some foo logic
}

const barMiddleware = (req, res, next) => {
  // some bar logic
}

app.use(injectMiddleware(
  [
    authMiddleware,
    fooMiddleware,
  ],
  [
    // Passing the app.[METHOD] as the parameter.
    app.get('/secrets', (req, res, next) => res.send('secrets'));

    // Mount barMiddleware itself
    app.post('/secrets', barMiddleware, (req, res, next) => res.send('ok'));
  ],
));

and this is the result:

app.get('/secrets', authMiddleware, fooMiddleware, (req, res, next) => res.send('secrets'));
app.post('/secrets', authMiddleware, fooMiddleware, barMiddleware, (req, res, next) => res.send('ok'));

Solution 7:[7]

in express 4 to grouping your routes, you should create some changes :

  • seperate route files in multiple files like admin and front
  • pass the router to the divided route files in routes/index.js file
const express = require('express')
require('express-group-routes');
const router = express.Router()

require('./admin/web.router')(router)
require('./front/web.router')(router)

module.exports = router
  • in each files we can use groups, middlewares and prefixes, like below
const adminPrefix = 'admin'
module.exports = function (router) {
    router.use(`\${adminPrefix}`, [ adminMiddleware ]);
    router.group(`/${adminPrefix}`, (router) => {
        router.get('/', home.index)
    });
}

Solution 8:[8]

You can use an npm module

Express group route

here is a code example from npm official module

var app = require('express');
require('express-group-routes');
 
app.group("/api/v1", (router) => {
    router.get("/login", loginController.store); // /api/v1/login 
});

Solution 9:[9]

Create the group method

export const group = ((callback: (router: Router) => void) => {
  const router = express.Router();
  callback(router);
  return router;
});

Use the group method

import { group } from './relative/path/to/group/method'

const apiRouter = express.Router();

apiRouter.use('/foo', group((router) => {
  router.get('/bar', (req, res) => {
    res.send('Hello World');
  });
}));

This will create a new GET route to "/foo/bar"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Melle
Solution 2
Solution 3 yadav-durgesh
Solution 4 jshawl
Solution 5
Solution 6
Solution 7 ahmad_mhm
Solution 8 Prashant Sharma
Solution 9 jessyp98