How to get all registered routes in Express?

node.jsExpress

node.js Problem Overview


I have a web application built using Node.js and Express. Now I would like to list all registered routes with their appropriate methods.

E.g., if I have executed

app.get('/', function (...) { ... });
app.get('/foo/:id', function (...) { ... });
app.post('/foo/:id', function (...) { ... });

I would like to retrieve an object (or something equivalent to that) such as:

{
  get: [ '/', '/foo/:id' ],
  post: [ '/foo/:id' ]
}

Is this possible, and if so, how?

node.js Solutions


Solution 1 - node.js

express 3.x

Okay, found it myself ... it's just app.routes :-)

express 4.x

Applications - built with express()

> app._router.stack

Routers - built with express.Router()

> router.stack

Note: The stack includes the middleware functions too, it should be filtered to get the "routes" only.

Solution 2 - node.js

app._router.stack.forEach(function(r){
  if (r.route && r.route.path){
    console.log(r.route.path)
  }
})

Solution 3 - node.js

DEBUG=express:* node index.js

If you run your app with the above command, it will launch your app with DEBUG module and gives routes, plus all the middleware functions that are in use.

You can refer: ExpressJS - Debugging and debug.

Solution 4 - node.js

This gets routes registered directly on the app (via app.VERB) and routes that are registered as router middleware (via app.use). Express 4.11.0

//////////////
app.get("/foo", function(req,res){
    res.send('foo');
});

//////////////
var router = express.Router();

router.get("/bar", function(req,res,next){
    res.send('bar');
});

app.use("/",router);


//////////////
var route, routes = [];

app._router.stack.forEach(function(middleware){
    if(middleware.route){ // routes registered directly on the app
        routes.push(middleware.route);
    } else if(middleware.name === 'router'){ // router middleware 
        middleware.handle.stack.forEach(function(handler){
            route = handler.route;
            route && routes.push(route);
        });
    }
});

// routes:
// {path: "/foo", methods: {get: true}}
// {path: "/bar", methods: {get: true}}

Solution 5 - node.js

Here's a little thing I use just to get the registered paths in express 4.x

app._router.stack          // registered routes
  .filter(r => r.route)    // take out all the middleware
  .map(r => r.route.path)  // get all the paths

Solution 6 - node.js

I have adapted an old post that is no longer online for my needs. I've used express.Router() and registered my routes like this:

var questionsRoute = require('./BE/routes/questions');
app.use('/api/questions', questionsRoute);

I renamed the document.js file in apiTable.js and adapted it like this:

module.exports =  function (baseUrl, routes) {
    var Table = require('cli-table');
    var table = new Table({ head: ["", "Path"] });
    console.log('\nAPI for ' + baseUrl);
    console.log('\n********************************************');

    for (var key in routes) {
        if (routes.hasOwnProperty(key)) {
	        var val = routes[key];
	        if(val.route) {
		        val = val.route;
		        var _o = {};
		        _o[val.stack[0].method]  = [baseUrl + val.path]; 	
		        table.push(_o);
	        }		
        }
    }

    console.log(table.toString());
    return table;
};

then i call it in my server.js like this:

var server = app.listen(process.env.PORT || 5000, function () {
    require('./BE/utils/apiTable')('/api/questions', questionsRoute.stack);
});

The result looks like this:

Result example

It's just an example but might be of use.. i hope..

Solution 7 - node.js

Hacky copy/paste answer courtesy of Doug Wilson on the express github issues. Dirty but works like a charm.

function print (path, layer) {
  if (layer.route) {
    layer.route.stack.forEach(print.bind(null, path.concat(split(layer.route.path))))
  } else if (layer.name === 'router' && layer.handle.stack) {
    layer.handle.stack.forEach(print.bind(null, path.concat(split(layer.regexp))))
  } else if (layer.method) {
    console.log('%s /%s',
      layer.method.toUpperCase(),
      path.concat(split(layer.regexp)).filter(Boolean).join('/'))
  }
}

function split (thing) {
  if (typeof thing === 'string') {
    return thing.split('/')
  } else if (thing.fast_slash) {
    return ''
  } else {
    var match = thing.toString()
      .replace('\\/?', '')
      .replace('(?=\\/|$)', '$')
      .match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//)
    return match
      ? match[1].replace(/\\(.)/g, '$1').split('/')
      : '<complex:' + thing.toString() + '>'
  }
}

app._router.stack.forEach(print.bind(null, []))

Produces

screengrab

Solution 8 - node.js

https://www.npmjs.com/package/express-list-endpoints works pretty well.

Example

Usage:

const all_routes = require('express-list-endpoints');
console.log(all_routes(app));

Output:

[ { path: '*', methods: [ 'OPTIONS' ] },
  { path: '/', methods: [ 'GET' ] },
  { path: '/sessions', methods: [ 'POST' ] },
  { path: '/sessions', methods: [ 'DELETE' ] },
  { path: '/users', methods: [ 'GET' ] },
  { path: '/users', methods: [ 'POST' ] } ]

Solution 9 - node.js

json output

function availableRoutes() {
  return app._router.stack
    .filter(r => r.route)
    .map(r => {
      return {
        method: Object.keys(r.route.methods)[0].toUpperCase(),
        path: r.route.path
      };
    });
}

console.log(JSON.stringify(availableRoutes(), null, 2));

looks like this:

[  {    "method": "GET",    "path": "/api/todos"  },  {    "method": "POST",    "path": "/api/todos"  },  {    "method": "PUT",    "path": "/api/todos/:id"  },  {    "method": "DELETE",    "path": "/api/todos/:id"  }]

string output

function availableRoutesString() {
  return app._router.stack
    .filter(r => r.route)
    .map(r => Object.keys(r.route.methods)[0].toUpperCase().padEnd(7) + r.route.path)
    .join("\n")
}

console.log(availableRoutesString());

looks like this:

GET    /api/todos  
POST   /api/todos  
PUT    /api/todos/:id  
DELETE /api/todos/:id

these are based on @corvid's answer

hope this helps

Solution 10 - node.js

You can implement a /get-all-routes API:

const express = require("express");
const app = express();

app.get("/get-all-routes", (req, res) => {  
  let get = app._router.stack.filter(r => r.route && r.route.methods.get).map(r => r.route.path);
  let post = app._router.stack.filter(r => r.route && r.route.methods.post).map(r => r.route.path);
  res.send({ get: get, post: post });
});

const listener = app.listen(process.env.PORT, () => {
  console.log("Your app is listening on port " + listener.address().port);
});

Here is a demo: https://glitch.com/edit/#!/get-all-routes-in-nodejs

Solution 11 - node.js

A function to log all routes in express 4 (can be easily tweaked for v3~)

function space(x) {
    var res = '';
    while(x--) res += ' ';
    return res;
}

function listRoutes(){
    for (var i = 0; i < arguments.length;  i++) {
        if(arguments[i].stack instanceof Array){
            console.log('');
            arguments[i].stack.forEach(function(a){
                var route = a.route;
                if(route){
                    route.stack.forEach(function(r){
                        var method = r.method.toUpperCase();
                        console.log(method,space(8 - method.length),route.path);
                    })
                }
            });
        }
    }
}

listRoutes(router, routerAuth, routerHTML);

Logs output:

GET       /isAlive
POST      /test/email
POST      /user/verify

PUT       /login
POST      /login
GET       /player
PUT       /player
GET       /player/:id
GET       /players
GET       /system
POST      /user
GET       /user
PUT       /user
DELETE    /user

GET       /
GET       /login

Made this into a NPM https://www.npmjs.com/package/express-list-routes

Solution 12 - node.js

I was inspired by Labithiotis's express-list-routes, but I wanted an overview of all my routes and brute urls in one go, and not specify a router, and figure out the prefix each time. Something I came up with was to simply replace the app.use function with my own function which stores the baseUrl and given router. From there I can print any table of all my routes.

NOTE this works for me because I declare my routes in a specific routes file (function) which gets passed in the app object, like this:

// index.js
[...]
var app = Express();
require(./config/routes)(app);

// ./config/routes.js
module.exports = function(app) {
    // Some static routes
    app.use('/users', [middleware], UsersRouter);
    app.use('/users/:user_id/items', [middleware], ItemsRouter);
    app.use('/otherResource', [middleware], OtherResourceRouter);
}

This allows me to pass in another 'app' object with a fake use function, and I can get ALL the routes. This works for me (removed some error checking for clarity, but still works for the example):

// In printRoutes.js (or a gulp task, or whatever)
var Express = require('express')
  , app     = Express()
  , _       = require('lodash')

// Global array to store all relevant args of calls to app.use
var APP_USED = []

// Replace the `use` function to store the routers and the urls they operate on
app.use = function() {
  var urlBase = arguments[0];

  // Find the router in the args list
  _.forEach(arguments, function(arg) {
    if (arg.name == 'router') {
      APP_USED.push({
        urlBase: urlBase,
        router: arg
      });
    }
  });
};

// Let the routes function run with the stubbed app object.
require('./config/routes')(app);

// GRAB all the routes from our saved routers:
_.each(APP_USED, function(used) {
  // On each route of the router
  _.each(used.router.stack, function(stackElement) {
    if (stackElement.route) {
      var path = stackElement.route.path;
      var method = stackElement.route.stack[0].method.toUpperCase();

      // Do whatever you want with the data. I like to make a nice table :)
      console.log(method + " -> " + used.urlBase + path);
    }
  });
});

This full example (with some basic CRUD routers) was just tested and printed out:

GET -> /users/users
GET -> /users/users/:user_id
POST -> /users/users
DELETE -> /users/users/:user_id
GET -> /users/:user_id/items/
GET -> /users/:user_id/items/:item_id
PUT -> /users/:user_id/items/:item_id
POST -> /users/:user_id/items/
DELETE -> /users/:user_id/items/:item_id
GET -> /otherResource/
GET -> /otherResource/:other_resource_id
POST -> /otherResource/
DELETE -> /otherResource/:other_resource_id

Using cli-table I got something like this:

┌────────┬───────────────────────┐
│        │ => Users              │
├────────┼───────────────────────┤
│ GET    │ /users/users          │
├────────┼───────────────────────┤
│ GET    │ /users/users/:user_id │
├────────┼───────────────────────┤
│ POST   │ /users/users          │
├────────┼───────────────────────┤
│ DELETE │ /users/users/:user_id │
└────────┴───────────────────────┘
┌────────┬────────────────────────────────┐
│        │ => Items                       │
├────────┼────────────────────────────────┤
│ GET    │ /users/:user_id/items/         │
├────────┼────────────────────────────────┤
│ GET    │ /users/:user_id/items/:item_id │
├────────┼────────────────────────────────┤
│ PUT    │ /users/:user_id/items/:item_id │
├────────┼────────────────────────────────┤
│ POST   │ /users/:user_id/items/         │
├────────┼────────────────────────────────┤
│ DELETE │ /users/:user_id/items/:item_id │
└────────┴────────────────────────────────┘
┌────────┬───────────────────────────────────┐
│        │ => OtherResources                 │
├────────┼───────────────────────────────────┤
│ GET    │ /otherResource/                   │
├────────┼───────────────────────────────────┤
│ GET    │ /otherResource/:other_resource_id │
├────────┼───────────────────────────────────┤
│ POST   │ /otherResource/                   │
├────────┼───────────────────────────────────┤
│ DELETE │ /otherResource/:other_resource_id │
└────────┴───────────────────────────────────┘

Which kicks ass.

Solution 13 - node.js

Within your app at /routes display your express route names

app.get('/routes', (req, res) => {
    res.send(app._router.stack
        .filter(r => r.route) 
        .map(r => r.route.path))
})

http://localhost:3000/routes

Solution 14 - node.js

Express 4

Given an Express 4 configuration with endpoints and nested routers

const express = require('express')
const app = express()
const router = express.Router()

app.get(...)
app.post(...)

router.use(...)
router.get(...)
router.post(...)

app.use(router)

Expanding the @caleb answer it is possible to obtain all routes recursively and sorted.

getRoutes(app._router && app._router.stack)
// =>
// [
//     [ 'GET', '/'], 
//     [ 'POST', '/auth'],
//     ...
// ]

/**
* Converts Express 4 app routes to an array representation suitable for easy parsing.
* @arg {Array} stack An Express 4 application middleware list.
* @returns {Array} An array representation of the routes in the form [ [ 'GET', '/path' ], ... ].
*/
function getRoutes(stack) {
        const routes = (stack || [])
                // We are interested only in endpoints and router middleware.
                .filter(it => it.route || it.name === 'router')
                // The magic recursive conversion.
                .reduce((result, it) => {
                        if (! it.route) {
                                // We are handling a router middleware.
                                const stack = it.handle.stack
                                const routes = getRoutes(stack)

                                return result.concat(routes)
                        }

                        // We are handling an endpoint.
                        const methods = it.route.methods
                        const path = it.route.path

                        const routes = Object
                                .keys(methods)
                                .map(m => [ m.toUpperCase(), path ])

                        return result.concat(routes)
                }, [])
                // We sort the data structure by route path.
                .sort((prev, next) => {
                        const [ prevMethod, prevPath ] = prev
                        const [ nextMethod, nextPath ] = next

                        if (prevPath < nextPath) {
                                return -1
                        }

                        if (prevPath > nextPath) {
                                return 1
                        }

                        return 0
                })

        return routes
}

For basic string output.

infoAboutRoutes(app)

Console output

/**
* Converts Express 4 app routes to a string representation suitable for console output.
* @arg {Object} app An Express 4 application
* @returns {string} A string representation of the routes.
*/
function infoAboutRoutes(app) {
        const entryPoint = app._router && app._router.stack
        const routes = getRoutes(entryPoint)

        const info = routes
                .reduce((result, it) => {
                        const [ method, path ] = it

                        return result + `${method.padEnd(6)} ${path}\n`
                }, '')

        return info
}

Update 1:

Due to the internal limitations of Express 4 it is not possible to retrieve mounted app and mounted routers. For example it is not possible to obtain routes from this configuration.

const subApp = express()
app.use('/sub/app', subApp)

const subRouter = express.Router()
app.use('/sub/route', subRouter)

Solution 15 - node.js

Need some adjusts but should work for Express v4. Including those routes added with .use().

function listRoutes(routes, stack, parent){
  
  parent = parent || '';
  if(stack){
    stack.forEach(function(r){
      if (r.route && r.route.path){
        var method = '';

        for(method in r.route.methods){
          if(r.route.methods[method]){
            routes.push({method: method.toUpperCase(), path: parent + r.route.path});
          }
        }       
        
      } else if (r.handle && r.handle.name == 'router') {
        const routerName = r.regexp.source.replace("^\\","").replace("\\/?(?=\\/|$)","");
        return listRoutes(routes, r.handle.stack, parent + routerName);
      }
    });
    return routes;
  } else {
    return listRoutes([], app._router.stack);
  }
}

//Usage on app.js
const routes = listRoutes(); //array: ["method: path", "..."]

edit: code improvements

Solution 16 - node.js

Slightly updated and more functional approach to @prranay's answer:

const routes = app._router.stack
    .filter((middleware) => middleware.route)
    .map((middleware) => `${Object.keys(middleware.route.methods).join(', ')} -> ${middleware.route.path}`)

console.log(JSON.stringify(routes, null, 4));

Solution 17 - node.js

Initialize express router

let router = require('express').Router();
router.get('/', function (req, res) {
    res.json({
        status: `API Its Working`,
        route: router.stack.filter(r => r.route)
           .map(r=> { return {"path":r.route.path, 
 "methods":r.route.methods}}),
        message: 'Welcome to my crafted with love!',
      });
   });   

Import user controller

var userController = require('./controller/userController');

User routes

router.route('/users')
   .get(userController.index)
   .post(userController.new);
router.route('/users/:user_id')
   .get(userController.view)
   .patch(userController.update)
   .put(userController.update)
   .delete(userController.delete);

Export API routes

module.exports = router;

Output

{"status":"API Its Working, APP Route","route": 
[{"path":"/","methods":{"get":true}}, 
{"path":"/users","methods":{"get":true,"post":true}}, 
{"path":"/users/:user_id","methods": ....}

Solution 18 - node.js

This worked for me

let routes = []
app._router.stack.forEach(function (middleware) {
    if(middleware.route) {
        routes.push(Object.keys(middleware.route.methods) + " -> " + middleware.route.path);
    }
});

console.log(JSON.stringify(routes, null, 4));

O/P:

[    "get -> /posts/:id",    "post -> /posts",    "patch -> /posts"]

Solution 19 - node.js

in all server this is how i do it

app.get('/', (req, res) => {
    console.log('home')
})
app.get('/home', (req, res) => {
    console.log('/home')
})

function list(id) {
    const path = require('path');

    const defaultOptions = {
        prefix: '',
        spacer: 7,
    };

    const COLORS = {
        yellow: 33,
        green: 32,
        blue: 34,
        red: 31,
        grey: 90,
        magenta: 35,
        clear: 39,
    };

    const spacer = (x) => (x > 0 ? [...new Array(x)].map(() => ' ').join('') : '');

    const colorText = (color, string) => `\u001b[${color}m${string}\u001b[${COLORS.clear}m`;

    function colorMethod(method) {
        switch (method) {
            case 'POST':
                return colorText(COLORS.yellow, method);
            case 'GET':
                return colorText(COLORS.green, method);
            case 'PUT':
                return colorText(COLORS.blue, method);
            case 'DELETE':
                return colorText(COLORS.red, method);
            case 'PATCH':
                return colorText(COLORS.grey, method);
            default:
                return method;
        }
    }

    function getPathFromRegex(regexp) {
        return regexp.toString().replace('/^', '').replace('?(?=\\/|$)/i', '').replace(/\\\//g, '/');
    }

    function combineStacks(acc, stack) {
        if (stack.handle.stack) {
            const routerPath = getPathFromRegex(stack.regexp);
            return [...acc, ...stack.handle.stack.map((stack) => ({ routerPath, ...stack }))];
        }
        return [...acc, stack];
    }

    function getStacks(app) {
        // Express 3
        if (app.routes) {
            // convert to express 4
            return Object.keys(app.routes)
                .reduce((acc, method) => [...acc, ...app.routes[method]], [])
                .map((route) => ({ route: { stack: [route] } }));
        }

        // Express 4
        if (app._router && app._router.stack) {
            return app._router.stack.reduce(combineStacks, []);
        }

        // Express 4 Router
        if (app.stack) {
            return app.stack.reduce(combineStacks, []);
        }

        // Express 5
        if (app.router && app.router.stack) {
            return app.router.stack.reduce(combineStacks, []);
        }

        return [];
    }

    function expressListRoutes(app, opts) {
        const stacks = getStacks(app);
        const options = {...defaultOptions, ...opts };

        if (stacks) {
            for (const stack of stacks) {
                if (stack.route) {
                    const routeLogged = {};
                    for (const route of stack.route.stack) {
                        const method = route.method ? route.method.toUpperCase() : null;
                        if (!routeLogged[method] && method) {
                            const stackMethod = colorMethod(method);
                            const stackSpace = spacer(options.spacer - method.length);
                            const stackPath = path.resolve(
                                [options.prefix, stack.routerPath, stack.route.path, route.path].filter((s) => !!s).join(''),
                            );
                            console.info(stackMethod, stackSpace, stackPath);
                            routeLogged[method] = true;
                        }
                    }
                }
            }
        }

    };

    expressListRoutes(app)
}

list(1);

if you run it then this will happen

GET C:
GET C:\home

Solution 20 - node.js

On Express 3.5.x, I add this before starting the app to print the routes on my terminal :

var routes = app.routes;
for (var verb in routes){
    if (routes.hasOwnProperty(verb)) {
      routes[verb].forEach(function(route){
        console.log(verb + " : "+route['path']);
      });
    }
}

Maybe it can help...

Solution 21 - node.js

So I was looking at all the answers.. didn't like most.. took some from a few.. made this:

const resolveRoutes = (stack) => {
  return stack.map(function (layer) {
    if (layer.route && layer.route.path.isString()) {
      let methods = Object.keys(layer.route.methods);
      if (methods.length > 20)
        methods = ["ALL"];

      return {methods: methods, path: layer.route.path};
    }

    if (layer.name === 'router')  // router middleware
      return resolveRoutes(layer.handle.stack);

  }).filter(route => route);
};

const routes = resolveRoutes(express._router.stack);
const printRoute = (route) => {
  if (Array.isArray(route))
    return route.forEach(route => printRoute(route));

  console.log(JSON.stringify(route.methods) + " " + route.path);
};

printRoute(routes);

not the prettiest.. but nested, and does the trick

also note the 20 there... I just assume there will not be a normal route with 20 methods.. so I deduce it is all..

Solution 22 - node.js

route details are listing route for "express": "4.x.x",

import {
  Router
} from 'express';
var router = Router();

router.get("/routes", (req, res, next) => {
  var routes = [];
  var i = 0;
  router.stack.forEach(function (r) {
    if (r.route && r.route.path) {
      r.route.stack.forEach(function (type) {
        var method = type.method.toUpperCase();
        routes[i++] = {
          no:i,
          method: method.toUpperCase(),
          path: r.route.path
        };
      })
    }
  })

  res.send('<h1>List of routes.</h1>' + JSON.stringify(routes));
});

SIMPLE OUTPUT OF CODE

List of routes.

[{"no":1,"method":"POST","path":"/admin"},{"no":2,"method":"GET","path":"/"},{"no":3,"method":"GET","path":"/routes"},{"no":4,"method":"POST","path":"/student/:studentId/course/:courseId/topic/:topicId/task/:taskId/item"},{"no":5,"method":"GET","path":"/student/:studentId/course/:courseId/topic/:topicId/task/:taskId/item"},{"no":6,"method":"PUT","path":"/student/:studentId/course/:courseId/topic/:topicId/task/:taskId/item/:itemId"},{"no":7,"method":"DELETE","path":"/student/:studentId/course/:courseId/topic/:topicId/task/:taskId/item/:itemId"}]

Solution 23 - node.js

Just use this npm package, it will give the web-output as well as terminal output in nice formatted table view.

enter image description here

https://www.npmjs.com/package/express-routes-catalogue

Solution 24 - node.js

For express 4.x

Here's a gross 1 liner that works with routes added to app and routes added to express.Router().

It returns this structure.

[
    {
        "path": "/api",
        "methods": {
            "get": true
        }
    },
    {
        "path": "/api/servermembers/",
        "methods": {
            "get": true
        }
    },
    {
        "path": "/api/servermembers/find/:query",
        "methods": {
            "get": true
        }
    }
]

Modules that use express.Router() would need to export like this:

module.exports = {
  router,
  path: "/servermembers",
};

And be added like this:

app.use(`/api${ServerMemberRoutes.path}`, ServerMemberRoutes.router);
app.get(
  "/api",
  /**
   * Gets the API's available routes.
   * @param {request} _req
   * @param {response} res
   */
  (_req, res) => {
    res.json(
      [app._router, ServerMemberRoutes]
        .map((routeInfo) => ({
          entityPath: routeInfo.path || "",
          stack: (routeInfo?.router?.stack || routeInfo.stack).filter(
            (stack) => stack.route
          ),
        }))
        .map(({ entityPath, stack }) =>
          stack.map(({ route: { path, methods } }) => ({
            path: entityPath ? `/api${entityPath}${path}` : path,
            methods,
          }))
        ).flat()
    );
  }
);

Of course, the /api base url prefix could be stored in a variable as well if desired.

Solution 25 - node.js

In express 4.*

//Obtiene las rutas declaradas de la API
    let listPathRoutes: any[] = [];
    let rutasRouter = _.filter(application._router.stack, rutaTmp => rutaTmp.name === 'router');
    rutasRouter.forEach((pathRoute: any) => {
        let pathPrincipal = pathRoute.regexp.toString();
        pathPrincipal = pathPrincipal.replace('/^\\','');
        pathPrincipal = pathPrincipal.replace('?(?=\\/|$)/i','');
        pathPrincipal = pathPrincipal.replace(/\\\//g,'/');
        let routesTemp = _.filter(pathRoute.handle.stack, rutasTmp => rutasTmp.route !== undefined);
        routesTemp.forEach((route: any) => {
            let pathRuta = `${pathPrincipal.replace(/\/\//g,'')}${route.route.path}`;
            let ruta = {
                path: pathRuta.replace('//','/'),
                methods: route.route.methods
            }
            listPathRoutes.push(ruta);
        });
    });console.log(listPathRoutes)

Solution 26 - node.js

This one worked for me

// Express 4.x
function getRoutes(stacks: any, routes: { path: string; method: string }[] = [], prefix: string = ''): { path: string; method: string }[] {
  for (const stack of stacks) {
    if (stack.route) {
      routes.push({ path: `${prefix}${stack.route.path}`, method: stack.route.stack[0].method });
    }
    if (stack && stack.handle && stack.handle.stack) {
      let stackPrefix = stack.regexp.source.match(/\/[A-Za-z0-9_-]+/g);

      if (stackPrefix) {
        stackPrefix = prefix + stackPrefix.join('');
      }

      routes.concat(getRoutes(stack.handle.stack, routes, stackPrefix));
    }
  }
  return routes;
}

Solution 27 - node.js

const routes = {}
function routerRecursion(middleware, pointer, currentName) {
  if (middleware.route) { // routes registered directly on the app
    if (!Array.isArray(pointer['routes'])) {
      pointer['routes'] = []
    }
    const routeObj = {
      path: middleware.route.path,
      method: middleware.route.stack[0].method
    }
    pointer['routes'].push(routeObj)
  } else if (middleware.name === 'router') { // inside router
    const current = middleware.regexp.toString().replace(/\/\^\\\//, '').replace(/\\\/\?\(\?\=\\\/\|\$\)\/\i/, '')
    pointer[current] = {}
    middleware.handle.stack.forEach(function (handler) {
      routerRecursion(handler, pointer[current], current)
    });
  }
}
app._router.stack.forEach(function (middleware) {
  routerRecursion(middleware, routes, 'main')
});
console.log(routes);

app._router.stack.forEach(function (middleware) { routerRecursion(middleware, routes, 'main') }); console.log(routes);

Solution 28 - node.js

Static code analysis approach.

This tool analyzes source code and shows routing info without starting a server.

npx express-router-dependency-graph --rootDir=path/to/project
# json or markdown output

https://github.com/azu/express-router-dependency-graph

Example output:

File Method Routing Middlewares FilePath
user/index.ts
get /getUserById requireView user/index.ts#L1-3
get /getUserList requireView user/index.ts#L4-6
post /updateUserById requireEdit user/index.ts#L8-10
post /deleteUserById requireEdit user/index.ts#L12-20
game/index.ts
get /getGameList requireView game/index.ts#L1-3
get /getGameById requireView game/index.ts#L4-6
post /updateGameById requireEdit game/index.ts#L8-10
post /deleteGameById requireEdit game/index.ts#L12-20

Solution 29 - node.js

I published a package that prints all middleware as well as routes, really useful when trying to audit an express application. You mount the package as middleware, so it even prints out itself:

https://github.com/ErisDS/middleware-stack-printer

It prints a kind of tree like:

- middleware 1
- middleware 2
- Route /thing/
- - middleware 3
- - controller (HTTP VERB)  

Solution 30 - node.js

Here is a one-line function to pretty-print the routes in an Express app:

const getAppRoutes = (app) => app._router.stack.reduce(
  (acc, val) => acc.concat(
    val.route ? [val.route.path] :
      val.name === "router" ? val.handle.stack.filter(
        x => x.route).map(
          x => val.regexp.toString().match(/\/[a-z]+/)[0] + (
            x.route.path === '/' ? '' : x.route.path)) : []) , []).sort();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGolo RodenView Question on Stackoverflow
Solution 1 - node.jsGolo RodenView Answer on Stackoverflow
Solution 2 - node.jseychuView Answer on Stackoverflow
Solution 3 - node.jsNBSamarView Answer on Stackoverflow
Solution 4 - node.jsCalebView Answer on Stackoverflow
Solution 5 - node.jscorvidView Answer on Stackoverflow
Solution 6 - node.jsmarco.marinangeliView Answer on Stackoverflow
Solution 7 - node.jsAlienWebguyView Answer on Stackoverflow
Solution 8 - node.jsaercolinoView Answer on Stackoverflow
Solution 9 - node.jsezekillsView Answer on Stackoverflow
Solution 10 - node.jsffmaerView Answer on Stackoverflow
Solution 11 - node.jsLabithiotisView Answer on Stackoverflow
Solution 12 - node.jsYann VanhalewynView Answer on Stackoverflow
Solution 13 - node.jsjasonleonhardView Answer on Stackoverflow
Solution 14 - node.jsDaniele OrlandoView Answer on Stackoverflow
Solution 15 - node.jslcssanchesView Answer on Stackoverflow
Solution 16 - node.jsSeedyROMView Answer on Stackoverflow
Solution 17 - node.jsChandan Kumar SinghView Answer on Stackoverflow
Solution 18 - node.jsprranayView Answer on Stackoverflow
Solution 19 - node.jsridheshView Answer on Stackoverflow
Solution 20 - node.jsDavid MansonView Answer on Stackoverflow
Solution 21 - node.jsTacB0sSView Answer on Stackoverflow
Solution 22 - node.jslasitha edirisooriyaView Answer on Stackoverflow
Solution 23 - node.jsNaveen DAView Answer on Stackoverflow
Solution 24 - node.jsNeil MView Answer on Stackoverflow
Solution 25 - node.jsDaniel OlmosView Answer on Stackoverflow
Solution 26 - node.jsdasdachsView Answer on Stackoverflow
Solution 27 - node.jsDavid DiamantView Answer on Stackoverflow
Solution 28 - node.jsazuView Answer on Stackoverflow
Solution 29 - node.jsErisDSView Answer on Stackoverflow
Solution 30 - node.jsslouchpieView Answer on Stackoverflow