如何在表达中获取所有注册路由?

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

E.g., 如果我表演了


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


我想得到一个对象 /或者相当于这个的东西/, 例如:


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


有可能,如果是这样,怎么样?

UPDATE:

同时,我创建了一个包 npm 题为
https://www.npmjs.com/package/get-routes
, 从此应用程序中删除路由,解决了此问题。 目前仅支持 Express 4.x, 但我认为现在是正常的。 只是 FYI.
已邀请:

八刀丁二

赞同来自:

表示 3.x

好的,发现自己 ... 这很简单
app.routes

:-/

表示 4.x

http://expressjs.com/4x/api.html#express
, 建造。
express//



app._router.stack


http://expressjs.com/4x/api.html#router
-postreated s。
express.Router//



router.stack


笔记

: 堆栈还包括中间软件功能,必须过滤才能获得

只要 "routes".

涵秋

赞同来自:

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

帅驴

赞同来自:

我改编了旧帖子,在网络中不再是网络,了解我的需求。
我用了 express.Router// 并注册其路线如下:


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


我重命名了文件 document.js 在 apiTable.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/;
}/;


结果如下所示:


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

裸奔

赞同来自:

这导致了路线直接注册的事实 /穿过 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 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

二哥

赞同来自:

DEBUG=express:* node index.js


如果使用上面的命令运行应用程序,它将使用模块启动应用程序
DEBUG

并将被给出路线,以及所有使用的中间软件功能。

您可以联系:
https://expressjs.com/en/guide/debugging.html

https://www.npmjs.com/package/debug
.

帅驴

赞同来自:

"袜子" 复制/插入答案是善意的
https://github.com/dougwilson

https://github.com/expressjs/express/issues/3308
. 脏,但像咒语一样工作。


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


生产

https://i.stack.imgur.com/CkUrX.png
</complex:'>

董宝中

赞同来自:

https://www.npmjs.com/package/ ... oints
它很好。

例子

使用:


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

帅驴

赞同来自:

所有路线的注册功能 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

喜特乐

赞同来自:

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


他们是基于答案

我希望这个能帮上忙

知食

赞同来自:

我灵感了 express-list-routes Labitiotis,但我想一次概述我所有的路由和粗url,而不是指定路由器,每次都会计算前缀。 我想到了它是为了简单地替换功能 app.use 我自己的函数 baseUrl 和这个路由器。 从那里,我可以打印所有路线的任何表。

NOTE 它适用于我,因为我在特定路由文件中声明了我的路由。 /功能/ , 将其发送到应用程序对象,例如:


// 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' 用假使用功能,我可以得到 ALL 路线。 这个对我有用 /为了清楚起见,一些验证错误,但仍然有效/:


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


使用
https://www.npmjs.com/package/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 │
└────────┴───────────────────────────────────┘


什么是nadright屁股。

八刀丁二

赞同来自:

表示 4

给予

Express-4。

使用END和嵌套路由器配置


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/


https://i.stack.imgur.com/9Xt0A.png

/**
* 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", "..."]


编辑:代码改进

喜特乐

赞同来自:

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


这是演示版本:
[/url]

涵秋

赞同来自:

稍微更新和更新的答案方法 @prranay's:


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

二哥

赞同来自:

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


导入用户控制器


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


Export 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": ....}

冰洋

赞同来自:

它为我工作了


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

江南孤鹜

赞同来自:

在 Express 3.5.x 我在运行应用程序之前添加它以进行打印路由 terminal :


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

冰洋

赞同来自:

所以我正在寻找所有问题的答案......我不喜欢最多......我拿了一些东西 ... 这样做:


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 方法..所以我得出结论是所有的..

石油百科

赞同来自:

只需使用此包裹。 npm, 他将提供一个Web结论以及结论 terminal 以良好的格式化表格形式。

https://i.stack.imgur.com/iNnKn.png
https://www.npmjs.com/package/ ... logue

江南孤鹜

赞同来自:

在表达中 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/

二哥

赞同来自:

我发布了一个打印所有中间软件的包,以及路由,在尝试审核快速应用程序时非常有用。 您使用包作为中间软件,因此甚至打印:

https://github.com/ErisDS/middleware-stack-printer
他打印出像树上的东西:


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

龙天

赞同来自:

以下是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//;

要回复问题请先登录注册