如何在Express中获得所有注册的路线?
我有一个使用Node.js和Express构build的Web应用程序。 现在我想用适当的方法列出所有注册的路线。
如果我已经执行了
app.get('/', function (...) { ... }); app.get('/foo/:id', function (...) { ... }); app.post('/foo/:id', function (...) { ... });
我想检索一个对象(或者与之相当的东西),例如:
{ get: [ '/', '/foo/:id' ], post: [ '/foo/:id' ] }
这是可能的,如果是这样,怎么样?
更新:同时,我创build了一个名为get-routes的npm包,它从给定的应用程序中提取路线,从而解决了这个问题。 目前,只支持Express 4.x,但我想现在这没问题。 只是供参考。
expression3.x
好吧,我自己find了…这只是app.routes
🙂
expression4.x
应用程序 – 使用express()
构build
app._router.stack
路由器 – 用express.Router()
router.stack
注意 :堆栈也包含中间件function,应该仅对其进行过滤以获取“路由” 。
app._router.stack.forEach(function(r){ if (r.route && r.route.path){ console.log(r.route.path) } })
在Express 4中,您可以按照以下有用的指南进行操作: 列出所有restterminal
我已经适应了我的需求。 我用express.Router()和注册我的路线是这样的:
var questionsRoute = require('./BE/routes/questions'); app.use('/api/questions', questionsRoute);
我将apiTable.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); });
结果如下所示:
这只是一个例子,但可能是有用的..我希望..
这获得直接注册在应用程序(通过app.VERB)和路由注册为路由器中间件(通过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}}
这里有一点我只是为了得到注册的path快递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
用快递4logging所有路线的function(可以轻松调整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
我受到了Labithiotis的快速列表路线的启发,但是我想要一览我所有的路由和垃圾邮件,而不是指定一个路由器,并且每次都要找出前缀。 我想到的是简单地用我自己的函数replaceapp.use函数,该函数存储baseUrl和给定的路由器。 从那里我可以打印我所有路线的任何一张桌子。
注意这适用于我,因为我声明我的路线在一个特定的路线文件(函数),它被传递到应用程序对象,如下所示:
// 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); }
这使我可以通过一个假使用函数传入另一个“应用程序”对象,我可以得到所有的路线。 这适用于我(删除一些错误检查清晰,但仍然适用于例子):
// 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路由器)只是testing和打印出来:
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表我有这样的事情:
┌────────┬───────────────────────┐ │ │ => 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 │ └────────┴───────────────────────────────────┘
哪个踢屁股
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' ] } ]
在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']); }); } }
也许它可以帮助…
Hacky复制/粘贴答复道格·威尔逊在expressiongithub问题 。 脏,但像一个魅力。
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, []))
产生
这对我有效
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" ]