Soru Express'te kayıtlı tüm rotalar nasıl alınır?


Node.js ve Express kullanılarak oluşturulmuş bir web uygulamasına sahibim. Şimdi tüm kayıtlı rotaları uygun yöntemlerle listelemek istiyorum.

Evet, eğer idam ettiysem

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

Bir nesneyi (veya buna eşdeğer bir şey) almak istiyorum:

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

Bu mümkün mü ve eğer mümkünse nasıl?


GÜNCELLEŞTİRME: Bu arada, adında bir npm paketi oluşturdum -Güzergah almak Bu sorunu çözen belirli bir uygulamadan rotaları çıkarır. Şu anda sadece Express 4.x destekleniyor, ancak şimdilik bunun iyi olduğunu düşünüyorum. Sadece FYI.


121
2018-02-18 10:46


Menşei




Cevaplar:


ekspres 3.x

Tamam, kendim buldum ... sadece app.routes :-)

ekspres 4.x

Uygulamalar - ile inşa express()

app._router.stack

Yönlendiriciler - ile inşa express.Router()

router.stack

Not: Yığın, ara katman yazılım işlevlerini de içerir; "Yolları" bir tek.


165
2018-02-18 11:11



0.10 düğümünü kullanıyorum ve app.routes.routes - yani JSON.stringify (app.routes.routes) yapabilirim demek - guy mograbi
Sadece Express 3.x için çalışır, 4.x değil. 4.x'te kontrol etmelisiniz app._router.stack - avetisk
Bu benim için beklendiği gibi çalışmadı. app._router app.use ('/ yol', otherRouter) 'dan rotaları içermiyor gibi görünmüyor; - Michael Cole
Bunun, canlı uygulamanın gerçekte bir web uygulaması başlatmadan tam olarak aynı rota dosyalarını çekecek bir komut satırı komut dosyasıyla entegre edilebilmesi için bir yolu var mı? - Lawrence I. Siden
En azından 4.13.1'de app._router.stack tanımlanmamış. - levigroker


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

40
2018-01-22 10:52



Çok basit ve çalışır. - Chris
Express Router (veya başka bir ara katman yazılımı) gibi bir şey kullanıyorsanız, @Caleb'in bu yaklaşımı genişleten biraz daha uzun bir cevap görmesi gerektiğini unutmayın. - Iain Collins


Express 4'te bu yararlı kılavuzu takip edebilirsiniz: Liste-all-dinlenme-bitiş noktaları

Bunu ihtiyaçlar için uyarladım. Express.Router () kullandım ve yollarımı şu şekilde kaydettim:

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

Document.js dosyasını apiTable.js olarak yeniden adlandırdım ve bunu şöyle uyarladım:

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

sonra bunu server.js’mde şöyle diyoruz:

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

Sonuç şöyle:

Result example

Bu sadece bir örnek ama kullanım olabilir .. umarım ..


26
2018-02-20 10:24



Bu, burada tanımlandığı gibi iç içe geçmiş rotalar için çalışmaz: stackoverflow.com/questions/25260818/... - thxmike


İşte ben sadece ifade 4.x kayıtlı yolları almak için kullandığım küçük bir şey

app._router.stack          // registered routes
  .filter(r => r.route)    // take out all the middleware
  .map(r => r.route.path)  // get all the paths

22
2018-01-29 16:12



console.log (server._router.stack.map (r => r.route) .filter (r => r) .map (r =>${Object.keys(r.methods).join(', ')} ${r.path})) - standup75


Bu, doğrudan uygulamaya (app.VERB aracılığıyla) ve yönlendirici ara yazılımına (app.use aracılığıyla) kaydedilen rotalara kaydedilen rotaları alır. 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}}

21
2018-01-28 18:34



Mükemmel, Express router gibi middleware ile ayarlanan ekran rotalarını nasıl alacağınızı gösteren bir örnek için teşekkürler. - Iain Collins


Express 4'teki tüm rotaları kaydetmek için bir fonksiyon (v3 ~ için kolayca ayarlanabilir)

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

Günlük çıktıları:

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

Bunu bir NPM'ye dönüştürdü https://www.npmjs.com/package/express-list-routes


6
2017-10-09 09:51



Bu benim için beklendiği gibi çalışmadı. app._router app.use ('/ yol', otherRouter) 'dan rotaları içermiyor gibi görünmüyor; - Michael Cole
@MichaelCole Golo Roden'den aşağıdaki cevaba baktınız mı? - Labithiotis
@ Dazzler13 Bir saat boyunca bununla oynadım ve çalışmaya başlayamadım. Express 4.0. Uygulamayı, yönlendiriciyi yaptı, app.use (yol, yönlendirici), yönlendirici rotaları app._router'da görünmedi. Örnek? - Michael Cole
Aşağıdaki @Caleb gelen örnek, bu sizin sorun buysa express.Router gibi bir şeyle ele alınan rotalar için iyi çalışır. Middleware (express.Router dahil) ile ayarlanmış rotaların hemen görünmeyebileceğini ve app._router'da kontrol etmeden önce (@Caleb'den gelen yaklaşımı kullanarak) kısa bir gecikme eklemeniz gerekebileceğini unutmayın. - Iain Collins


Labithiotis'in ekspres-liste-rotalarından esinlendim, ama bir seferde tüm rotalarım ve kaba urllerimi genel olarak görmek istedim ve bir yönlendirici belirtmemek ve her seferinde ön eki bulmak istedim. Geldiğim bir şey, app.use işlevini baseUrl ve yönlendiriciyi kaydeden kendi işlevimle değiştirmekti. Oradan tüm rotalarımın herhangi bir tablosunu yazdırabilirim.

Not Bu benim için çalışır, çünkü uygulama yollarımda geçen belirli bir güzergah dosyasında (işlev) yollarımı bildiririm:

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

Bu sahte bir kullanım fonksiyonu ile başka bir 'uygulama' nesnesini geçirmeme izin verir ve TÜM yolları yollayabilirim. Bu benim için çalışıyor (açıklık denetimi için bazı hatalar kaldırıldı, ancak yine de örnek için çalışıyor):

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

Bu tam örnek (bazı temel CRUD yönlendiricilerle) test edilmiş ve yazdırılmıştır:

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

kullanma cli masa Böyle bir şeyim var:

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

Hangi kıçını tekmeliyor.


4
2017-07-19 13:00





Hacky kopyala / yapıştır cevabı nezaket Doug Wilson üzerinde github sorunlarını aç. Kirli ama cazibe gibi çalışır.

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

üretir

screengrab


4
2017-09-25 05:10



Rotalar neden ayrı değil? - Vladimir Vukanac
Express 4.15 ile benim için çalışan tek kişi bu. Diğerlerinin hiçbiri tam yolunu vermedi. Tek uyarı, varsayılan kök yolunu geri vermemesidir - hiçbiri yapmaz. - Shane


https://www.npmjs.com/package/express-list-endpoints oldukça iyi çalışıyor.

Örnek

Kullanımı:

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

Çıktı:

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

2
2018-06-06 17:45



Bu şu şekilde çalışmıyor: server = express(); app1 = express(); server.use('/app1', app1); ... - Danosaure


@ Prranay'ın cevabına biraz güncellenmiş ve daha işlevsel bir yaklaşım:

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

2
2017-12-13 23:35