Como obter todas as rotas registradas no Express?

181

Eu tenho um aplicativo da Web criado usando o Node.js e o Express. Agora eu gostaria de listar todas as rotas registradas com seus métodos apropriados.

Por exemplo, se eu executei

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

Gostaria de recuperar um objeto (ou algo equivalente a isso) como:

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

Isso é possível e, se sim, como?


ATUALIZAÇÃO: Enquanto isso, eu criei um pacote npm chamado get-routes que extrai as rotas de um determinado aplicativo, que resolve esse problema. Atualmente, apenas o Express 4.x é suportado, mas acho que por enquanto está bom. Apenas para sua informação.

Golo Roden
fonte
Todas as soluções que tentei não funcionam quando você possui roteadores definidos. Ele só funciona por rota - que não me dá toda a url para aquela rota em meu aplicativo ...
cara Mograbi
1
@guymograbi você pode querer olhar para stackoverflow.com/a/55589657/6693775
nbsamar

Respostas:

230

express 3.x

Ok, encontrei-me ... é apenas app.routes :-)

express 4.x

Aplicações - construídas comexpress()

app._router.stack

Roteadores - construídos comexpress.Router()

router.stack

Nota : A pilha também inclui as funções de middleware; ela deve ser filtrada para obter apenas as "rotas" .

Golo Roden
fonte
Eu estou usando nó 0,10 e foi app.routes.routes- o que significa que eu poderia fazer JSON.stringify (app.routes.routes)
cara Mograbi
7
Funciona apenas para o Express 3.x, não 4.x. No 4.x, você deve verificarapp._router.stack
avetisk
14
Isso não funcionou como esperado para mim. app._router parece não incluir rotas de app.use ('/ path', otherRouter);
Michael Cole
Existe alguma maneira de isso ser integrado a um script de linha de comando que extraia exatamente os mesmos arquivos de rota que o aplicativo ativo, sem realmente iniciar um aplicativo Web?
Lawrence I. Siden
5
Pelo menos no expresso 4.13.1 app._router.stacké indefinido.
levigroker
54
app._router.stack.forEach(function(r){
  if (r.route && r.route.path){
    console.log(r.route.path)
  }
})
eychu
fonte
1
Observe que, se você estiver usando algo como o Express Router (ou outro middleware), verá a resposta @Caleb um pouco mais longa que se expande nessa abordagem.
Iain Collins
31

Isso obtém rotas registradas diretamente no aplicativo (via app.VERB) e rotas registradas como middleware do roteador (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}}
Caleb
fonte
1
Excelente, obrigado por um exemplo que mostra como definir rotas de exibição definidas através de middleware como o roteador Express.
Iain Collins
31

Adaptei um post antigo que não está mais online para minhas necessidades. Eu usei express.Router () e registrei minhas rotas assim:

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

Renomeei o arquivo document.js em apiTable.js e o adaptei da seguinte maneira:

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;
};

então eu chamo no meu server.js assim:

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

O resultado fica assim:

Exemplo de resultado

É apenas um exemplo, mas pode ser útil .. espero ..

marco.marinangeli
fonte
2
Isso não funciona para rotas aninhadas como identificado aqui: stackoverflow.com/questions/25260818/...
2
Cuidado com o link nesta resposta! Ele me redirecionou para um site aleatório e forçou um download para o meu computador.
Tyler Bell
29

Aqui está uma coisinha que eu uso apenas para obter os caminhos registrados no 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
Corvid
fonte
console.log (server._router.stack.map (r => r.route) .filter (r => r) .Map (r => ${Object.keys(r.methods).join(', ')} ${r.path}))
standup75
onde você coloca isso, em app.js ??
Juan Juan
21

DEBUG=express:* node index.js

Se você executar seu aplicativo com o comando acima, ele será iniciado com o DEBUGmódulo e fornecerá rotas, além de todas as funções de middleware que estão em uso.

Você pode consultar: ExpressJS - Depuração e depuração .

nbsamar
fonte
3
De longe a melhor resposta ... um env var!
Jeef 02/04
Na verdade, resposta mais útil. @ nbsamar Você pode até expandi-lo para dizer para usar DEBUG=express:pathsapenas para ver a saída do caminho e não todas as outras mensagens de depuração. Obrigado!
Mark Edington
19

Resposta copiada / colada por Hacky, cortesia de Doug Wilson, sobre os problemas expressos do github . Sujo, mas funciona como um encanto.

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, []))

Produz

captura de tela

AlienWebguy
fonte
Por que as rotas não são distintas?
Vladimir Vukanac
1
Este é o único que funcionou para mim com o Express 4.15. Nenhum dos outros deu o caminho completo. A única ressalva é que ele não devolve o caminho raiz padrão / - nenhum deles.
21718 Shane
Não entendo por que você vincula argumentos print?
ZzZombo # 15/18
@ZzZombo perguntou a Doug Wilson, ele escreveu. Você provavelmente pode limpar tudo isso, se quiser.
AlienWebguy
11

https://www.npmjs.com/package/express-list-endpoints funciona muito bem.

Exemplo

Uso:

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

Resultado:

[ { path: '*', methods: [ 'OPTIONS' ] },
  { path: '/', methods: [ 'GET' ] },
  { path: '/sessions', methods: [ 'POST' ] },
  { path: '/sessions', methods: [ 'DELETE' ] },
  { path: '/users', methods: [ 'GET' ] },
  { path: '/users', methods: [ 'POST' ] } ]
aercolino
fonte
2
Isso não funciona com: server = express(); app1 = express(); server.use('/app1', app1); ...
Danosaure
8

Uma função para registrar todas as rotas no express 4 (pode ser facilmente ajustado para a 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);

Registra a saída:

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

Transforme isso em um NPM https://www.npmjs.com/package/express-list-routes

Labithiotis
fonte
1
Isso não funcionou como esperado para mim. app._router parece não incluir rotas de app.use ('/ path', otherRouter);
Michael Cole
@MichaelCole Você olhou a resposta abaixo de Golo Roden?
precisa saber é o seguinte
@ Dazzler13 Brinquei com isso por uma hora e não consegui fazê-lo funcionar. Express 4.0. Aplicativo criado, roteador criado, app.use (caminho, roteador), rotas do roteador não aparecem no app._router. Exemplo?
Michael Cole
O exemplo do @Caleb abaixo funciona bem para rotas tratadas com algo como express.Router, se esse for o seu problema. Observe que as rotas definidas com o middleware (incluindo express.Router) podem não aparecer imediatamente e você pode precisar adicionar um pequeno atraso antes de procurá-las no app._router (mesmo usando a abordagem do @Caleb).
Iain Collins
8

saída json

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));

se parece com isso:

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

saída de string

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());

se parece com isso:

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

estes são baseados na resposta de @ corvid

espero que isto ajude

ezekills
fonte
5

Fui inspirado pelas rotas de lista expressa do Labithiotis, mas queria uma visão geral de todas as minhas rotas e URLs brutos de uma só vez, e não especificar um roteador, e descobrir o prefixo de cada vez. Algo que surgiu foi simplesmente substituir a função app.use por minha própria função, que armazena o baseUrl e o roteador fornecido. De lá, posso imprimir qualquer tabela de todas as minhas rotas.

OBSERVAÇÃO isso funciona para mim porque declaro minhas rotas em um arquivo de rotas específico (função) que é passado no objeto do aplicativo, assim:

// 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);
}

Isso permite que eu passe outro objeto 'app' com uma função de uso falso, e posso obter TODAS as rotas. Isso funciona para mim (removemos alguma verificação de erro para maior clareza, mas ainda funciona para o exemplo):

// 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);
    }
  });
});

Este exemplo completo (com alguns roteadores CRUD básicos) acabou de ser testado e impresso:

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

Usando cli-table, eu tenho algo como isto:

┌────────┬───────────────────────┐
         => 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 
└────────┴───────────────────────────────────┘

O que chuta a bunda.

Yann Vanhalewyn
fonte
4

Express 4

Dada uma configuração do Express 4 com terminais e roteadores aninhados

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

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

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

app.use(router)

Expandindo a resposta @caleb , é possível obter todas as rotas recursivamente e classificadas.

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
}

Para saída básica de strings.

infoAboutRoutes(app)

Saída do console

/**
* 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
}

Atualização 1:

Devido às limitações internas do Express 4, não é possível recuperar aplicativos e roteadores montados. Por exemplo, não é possível obter rotas a partir desta configuração.

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

const subRouter = express.Router()
app.use('/sub/route', subRouter)
Daniele Orlando
fonte
A listagem de rotas montadas funciona com este pacote: github.com/AlbertoFdzM/express-list-endpoints
jsaddwater
4

Precisa de alguns ajustes, mas deve funcionar para o Express v4. Incluindo as rotas adicionadas .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", "..."]

editar: aprimoramentos de código

lcssanches
fonte
3

Abordagem ligeiramente atualizada e mais funcional da resposta do @ prranay:

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));
SeedyROM
fonte
2

Isso funcionou para mim

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"
]
prranay
fonte
2

Inicializar o roteador expresso

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!',
      });
   });   

Importar controlador de usuário

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

Rotas do usuário

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);

Exportar rotas da API

module.exports = router;

Resultado

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

No Express 3.5.x, adiciono isso antes de iniciar o aplicativo para imprimir as rotas no meu terminal:

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

Talvez possa ajudar ...

David Manson
fonte
1

Você pode implementar uma /get-all-routesAPI:

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);
});

Aqui está uma demonstração: https://glitch.com/edit/#!/get-all-routes-in-nodejs

ffmaer
fonte
0

Então, eu estava olhando para todas as respostas .. não gostei mais .. tirei algumas de algumas .. fiz o seguinte:

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);

não é a mais bonita .. mas aninhada, e faz o truque

observe também os 20 lá ... Eu suponho que não haverá uma rota normal com 20 métodos .. então deduzo que é tudo ..

TacB0sS
fonte
0

os detalhes da rota estão listando a rota para "express": "4.xx",

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));
});

SAÍDA SIMPLES DE CÓDIGO

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"}
]
lasitha edirisooriya
fonte
0

Basta usar este pacote npm, ele fornecerá a saída da Web e a saída do terminal em uma bela exibição de tabela formatada.

insira a descrição da imagem aqui

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

NaveenDA
fonte
2
Este outro pacote tem muito mais aceitação. npmjs.com/package/express-list-endpoints . São 21.111 contra 34 downloads semanais. No entanto, express-routes-cataloguetambém exibe as rotas como HTML, mesmo que a outra não.
mayid
1
não é ruim, a documentação do pacote difere do nome real do pacote quando requerido e este pacote, como todos os outros mencionados, mostra apenas rotas de camada única onde está incluído
hamza khan
@hamzakhan ps obrigado pela atualização.Eu sou o autor, em breve será atualizado na documentação.
Vijay
-1

Aqui está uma função de uma linha para imprimir as rotas em um 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();
slouchpie
fonte
-2

Publiquei um pacote que imprime todo o middleware e rotas, realmente útil ao tentar auditar um aplicativo expresso. Você monta o pacote como middleware, para que ele mesmo se imprima:

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

Imprime um tipo de árvore como:

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