You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用express-promise-router的分层路由Express应用如何列出所有注册路由?

express-promise-router分层路由全量获取方案

实现原理

express-promise-router本质是对express原生Router的薄封装,实例内部仍保留原生Router的stack属性存储路由栈,第三方工具无法识别分层路由的核心原因是没有做递归遍历处理,只要按以下逻辑逐层解析即可拿到所有路由:

  • 每个express实例(包括app、各级子路由)的路由都存储在自身的stack数组中,数组每一项为layer对象
  • 若layer存在route属性,说明为最终接口路由,可直接获取请求方法和路径后缀
  • 若layer的name为router,说明为子路由挂载层,其handle属性(或包装后的handle.router属性)对应子路由实例,需拼接当前层级路径前缀后递归遍历子路由的stack

具体实现代码

/**
 * 提取所有路由
 * @param {Object} app express实例 / 顶层promise router实例
 * @param {String} basePath 根路径前缀,默认空
 * @returns {Array} 路由列表,包含path(完整路径)、methods(请求方法数组)
 */
function listAllRoutes(app, basePath = '') {
  const routes = [];

  function traverseStack(stack, currentPrefix) {
    stack.forEach(layer => {
      // 处理最终接口路由
      if (layer.route) {
        const fullPath = currentPrefix + layer.route.path;
        const methods = Object.keys(layer.route.methods).map(method => method.toUpperCase());
        routes.push({
          path: fullPath,
          methods: methods
        });
        return;
      }

      // 处理子路由层,兼容原生router和express-promise-router的包装结构
      const childRouter = layer.handle?.stack ? layer.handle : layer.handle?.router;
      if (layer.name === 'router' && childRouter?.stack) {
        // 提取子路由挂载前缀,兼容新旧版本express的路径取值
        let subPrefix = layer.path || '';
        if (!subPrefix) {
          // 旧版本express无layer.path属性,从正则反向提取路径
          subPrefix = layer.regexp.toString()
            .replace(/^\/\^/, '')
            .replace(/\\\/\?\(\?=\/\|\$\)/, '')
            .replace(/\\/g, '');
        }
        traverseStack(childRouter.stack, currentPrefix + subPrefix);
      }
    });
  }

  // 遍历根路由栈
  const rootStack = app._router?.stack || app.stack;
  if (rootStack) {
    traverseStack(rootStack, basePath);
  }

  return routes;
}

// 使用示例,服务启动完成后调用即可
const allRoutes = listAllRoutes(app);
// 打印所有路由
console.log('===== 项目所有路由列表 =====');
allRoutes.forEach(item => {
  console.log(`${item.methods.join(',')} ${item.path}`);
});

适配注意事项

  • 如果项目中存在正则格式的路由路径,可自行调整子前缀提取的正则逻辑适配业务规则
  • 支持任意层级的嵌套子路由,无需针对嵌套层数做额外配置
  • 如不需要从app实例遍历,也可以直接将顶层的promise router实例作为参数传入函数,可拿到相同结果

内容的提问来源于stack exchange,提问作者Subhi Samara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:36:03