232

Node.jsとExpressを使用して構築されたWebアプリケーションがあります。次に、登録されているすべてのルートを適切な方法で一覧表示します。

例:実行した場合

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

次のようなオブジェクト(またはそれに相当するもの)を取得したいと思います。

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

これは可能ですか?もしそうなら、どのように?

4

30 に答える 30

282

エクスプレス 3.x

さて、それを自分で見つけました...それはただですapp.routes:-)

エクスプレス 4.x

アプリケーション- で構築express()

app._router.stack

ルーター- で構築express.Router()

router.stack

: スタックにはミドルウェア関数も含まれています。 「ルート」のみを取得するようにフィルタリングする必要があります。

于 2013-02-18T11:11:55.607 に答える
69
app._router.stack.forEach(function(r){
  if (r.route && r.route.path){
    console.log(r.route.path)
  }
})
于 2015-01-22T10:52:56.137 に答える
44

これにより、アプリに直接登録されたルート (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}}
于 2015-01-28T18:34:55.817 に答える
38

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
于 2016-01-29T16:12:34.083 に答える
31

Express github issues に関するDoug Wilsonの厚意により、ハッキーなコピー/貼り付けの回答が提供されました。汚れていますが、魅力のように機能します。

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

プロデュース

スクリーングラブ

于 2017-09-25T05:10:08.867 に答える
10

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

于 2014-10-09T09:51:29.303 に答える
6

私は Labithiotis の express-list-routes に触発されましたが、すべてのルートとブルート URL を一度に概観し、ルーターを指定せず、毎回プレフィックスを見つけたいと考えていました。私が思いついたのは、 app.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 ルーターを使用) は、テストして印刷しただけです。

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 │
└────────┴───────────────────────────────────┘

これはお尻を蹴ります。

于 2015-07-19T13:00:41.347 に答える
1

Express 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']);
      });
    }
}

多分それは助けることができます...

于 2014-07-21T14:37:25.093 に答える
-1

急行で 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)
于 2020-07-18T19:14:17.807 に答える