如何获得所有已注册的快捷路线?

我有一个使用Node.js和Express构建的web应用程序。现在我想列出所有注册的路由及其相应的方法。

例如,如果我已经执行了

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

我想检索一个对象(或等价的东西),如:

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

这可能吗?如果可能,怎么做?

195743 次浏览

表达3.倍

好吧,我自己找到的……它只是app.routes:-)

表达4.倍

应用程序 -用express()构建

app._router.stack

路由器 -用express.Router()构建

router.stack

请注意:堆栈也包括中间件函数,应该过滤它以只得到“路线”

3.5号快车。x,我在启动应用程序打印我的终端上的路线之前添加了这个:

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

也许会有帮助……

在express 4中记录所有路由的功能(可以很容易地为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);

日志输出:

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

使这成为一个NPM https://www.npmjs.com/package/express-list-routes

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

这将获得直接在应用程序上注册的路由(通过app. verb)和注册为路由器中间件的路由(通过app.use)。表达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}}

我改编了一个旧帖子,它不再在线,以满足我的需要。 我已经使用express.Router()并像这样注册我的路由:

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

我在aptable .js中重命名了document.js文件,并进行了如下调整:

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

然后我在我的server.js中像这样调用它:

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

结果如下所示:

结果示例

这只是一个例子,但可能有用。我希望. .

我受到了Labithiotis的express-list-routes的启发,但我想一次浏览我所有的路由和brute url,而不是指定一个路由器,每次都要找出前缀。我想到的是用我自己的函数替换app.use函数,它存储baseUrl和给定的路由器。从那里,我可以打印所有路线的任何表格。

注:这对我来说是可行的,因为我在一个特定的routes文件(函数)中声明了我的路由,该文件在app对象中传递,就像这样:

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

这允许我传入另一个带有假使用函数的“app”对象,我可以获得所有的路线。这适用于我(删除了一些错误检查的清晰度,但仍然适用于示例):

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

这个完整的例子(包含一些基本的CRUD路由器)刚刚测试并打印出来:

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

使用cli-table我得到了类似这样的东西:

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

这太棒了。

这是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

https://www.npmjs.com/package/express-list-endpoints工作得很好。

例子

用法:

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

输出:

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

道格•威尔逊表达github问题上复制/粘贴答案。很脏,但很有效。

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

生产

screengrab

这对我很有效

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的答案进行了稍微更新和更实用的方法:

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

表达4

给定一个带有端点和嵌套路由器的表达4配置

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


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


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


app.use(router)

展开@caleb答案,可以递归地获得所有路由并排序。

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
}

用于基本字符串输出。

infoAboutRoutes(app)

控制台输出

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

更新1:

由于Express 4的内部限制,无法检索已安装的应用程序和已安装的路由器。例如,不可能从这个配置中获取路由。

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


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

需要一些调整,但应该适用于Express v4。包括那些用.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", "..."]

编辑:代码改进

所以我看了所有的答案。我不喜欢大多数…从一些人那里拿了一些。做了这个:

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

不是最漂亮的…但嵌套,并做到了这一点

还要注意这里的20…我只是假设不会有20种方法的正常路线。所以我推断这都是…

路线详细信息列出了“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));
});

简单的代码输出

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"}
]

我发布了一个可以打印所有中间件和路由的包,在尝试审计一个快速应用程序时非常有用。你把这个包作为中间件挂载,所以它甚至会自己打印出来:

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

它会印出一种树,就像:

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

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

看起来是这样的:

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

字符串输出

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

看起来是这样的:

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

这些都是基于@corvid的的答案

希望这能有所帮助

DEBUG=express:* node index.js

如果你用上面的命令运行你的应用程序,它将启动你的应用程序与DEBUG模块,并给出路由,以及所有正在使用的中间件函数。

你可以参考:ExpressJS -调试调试

只要使用这个npm包,它就会以格式化好的表格视图提供web输出和终端输出。

enter image description here

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

初始化快速路由器

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

导入用户控制器

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

用户线路

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

导出API路由

module.exports = router;

输出

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

下面是一个单行函数,用于漂亮地打印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();

你可以实现一个/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);
});


下面是一个演示:https://glitch.com/edit/ !/ get-all-routes-in-nodejs

在快车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)

在你的应用程序/routes中显示你的快捷路线名称

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

http://localhost:3000/routes

这个方法对我很管用

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

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

< p > app._router.stack。forEach(函数(中间件){ routerRecursion(中间件,路由,'main') }); < / p > console.log(路线);

静态代码分析方法。

该工具分析源代码并显示路由信息,而无需启动服务器。

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

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

示例输出:

文件 方法 路由 中间件) FilePath
用户/ index.ts
得到 / getUserById requireView 用户/ index.ts # L1-3
得到 / getUserList requireView 用户/ index.ts # L4-6
帖子 / updateUserById requireEdit 用户/ index.ts # L8-10
帖子 / deleteUserById requireEdit 用户/ index.ts # L12-20
游戏/ index.ts
得到 / getGameList requireView 游戏/ index.ts # L1-3
得到 / getGameById requireView 游戏/ index.ts # L4-6
帖子 / updateGameById requireEdit 游戏/ index.ts # L8-10
帖子 / deleteGameById requireEdit 游戏/ index.ts # L12-20

在所有服务器中,我都是这样做的

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

如果运行它,就会发生这种情况

GET C:
回家得到C: \ < / p >

特快4.x

下面是一个大体为1的程序,它处理添加到app的路由和添加到express.Router()的路由。

它返回这个结构。

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

使用express.Router()的模块需要像这样导出:

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

并像这样相加:

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

当然,如果需要的话,/api基本url前缀也可以存储在变量中。

最近,我一直在努力寻找一种可以很好地做到这一点的工具。我发现的每个解决方案/现有的npm包都有失败的极端情况,我的项目也有这些极端情况。我还想要一个可以用于我的项目的输出。

所以我创建了自己的工具:https://www.npmjs.com/package/express-route-parser

它还允许您通过中间件将任意元数据附加到路由。这可以以多种方式使用,例如将模式附加到路由。

看看它是否有用