code

Express에 등록된 모든 경로를 가져오는 방법은 무엇입니까?

starcafe 2023. 5. 23. 22:03
반응형

Express에 등록된 모든 경로를 가져오는 방법은 무엇입니까?

Node.js와 Express를 사용하여 만든 웹 애플리케이션이 있습니다.이제 등록된 모든 경로를 적절한 방법으로 나열하려고 합니다.

예: 실행한 경우

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

다음과 같은 개체(또는 이와 동등한 개체)를 검색하려고 합니다.

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

이것이 가능하며, 가능하다면 어떻게 가능합니까?

express 3.x

좋아요, 제가 직접 찾아냈어요...이건그저.app.routes:-)

express 4.x

응용프로그램 - 다음을 사용하여 구축됨express()

app._router.stack

라우터 - 로 구축됨express.Router()

router.stack

참고: 스택에는 미들웨어 기능도 포함되어 있으므로 "경로"만 가져오도록 필터링해야 합니다.

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

DEBUG=express:* node index.js

위의 명령으로 앱을 실행하면 앱이 실행됩니다.DEBUG사용 중인 모든 미들웨어 기능과 경로를 제공합니다.

다음을 참조할 수 있습니다: ExpressJS - 디버깅디버그.

이렇게 하면 앱에 직접 등록된 경로를 얻을 수 있습니다(앱을 통해)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}}

빠른 git 허브 문제에 대한 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, []))

프로듀스

스크린 그립

고속 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

더 이상 온라인 상태가 아닌 이전 게시물을 필요에 맞게 수정했습니다.급행을 이용해 봤어요.라우터() 및 다음과 같이 내 경로를 등록했습니다.

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

그런 다음 서버에서 다음과 같이 호출합니다.js:

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

결과는 다음과 같습니다.

결과 예제

예에 불과하지만 유용할 수도 있습니다.나는 희망합니다.

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

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의 대답을 기반으로 합니다.

이것이 도움이 되길 바랍니다.

다음을 구현할 수 있습니다./get-all-routesAPI:

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-flash-in-nodejs

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

의 앱 에서./routes 경로 을 표시

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

http://localhost:3000/http

저는 라비티오티스의 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 테이블을 사용하면 다음과 같은 이점을 얻을 수 있습니다.

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

바보 같은 짓.

익스프레스 4

엔드포인트 및 중첩된 라우터가 있는 Express 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", "..."]

편집: 코드 개선

@pranay의 답변에 약간 업데이트되고 더 기능적인 접근 방식:

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

고속 라우터 초기화

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

모든 서버에서 이것이 내가 하는 방법입니다.

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:
GET C:\home

이것은 나에게 효과가 있었습니다.

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에서는 터미널에서 경로를 인쇄하기 위해 앱을 시작하기 전에 다음을 추가합니다.

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의 경우

여기에 노선이 추가된 총 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 접두사는 원하는 경우 변수에도 저장할 수 있습니다.

그래서 저는 모든 답을 보고 있었습니다.가장 마음에 들지 않는..몇 개에서 몇 개를 가져갔어요다음을 만들었습니다.

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가지 방법으로는 정상적인 경로가 없을 것이라고 생각합니다.그래서 추측하건데 그게 다..

경로 세부 정보는 "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"}
]

이 npm 패키지를 사용하면 웹 출력과 터미널 출력을 멋진 형식의 테이블 뷰로 제공합니다.

여기에 이미지 설명 입력

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

정적 코드 분석 접근 방식.

이 도구는 서버를 시작하지 않고 소스 코드를 분석하고 라우팅 정보를 표시합니다.

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

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

출력 예:

파일 방법 라우팅 미들웨어 파일 경로
user/index.ts
얻다 /ID별 사용자 가져오기 보기 필요 user/index.ts#L1-3
얻다 /사용자 목록 가져오기 보기 필요 user/index.ts#L4-6
포스트. /UserById 업데이트 requiredEdit user/index.ts#L8-10
포스트. /DeleteUserById(ID별 사용자 삭제) requiredEdit user/index.ts#L12-20
게임/인덱스
얻다 /게임 목록 가져오기 보기 필요 game/index.ts#L1-3
얻다 /Id별 게임 가져오기 보기 필요 game/index.ts#L4-6
포스트. /updateGameById requiredEdit game/index.ts#L8-10
포스트. /ID별 게임 삭제 requiredEdit game/index.ts#L12-20

저는 최근에 이것을 잘 수행할 수 있는 도구를 찾는 데 어려움을 겪고 있었습니다.제가 찾은 모든 솔루션/기존 npm 패키지에는 실패한 코너 케이스가 있었고, 제 프로젝트에는 그러한 코너 케이스가 있었습니다.저는 또한 제 프로젝트에 사용할 수 있는 출력물을 원했습니다.

그래서 제가 직접 도구를 만들었습니다. https://www.npmjs.com/package/express-route-parser

또한 임의 메타데이터를 미들웨어를 통해 경로에 첨부할 수 있습니다.이것은 경로에 스키마를 첨부하는 등 다양한 방법으로 사용할 수 있습니다.

그것을 확인하고 도움이 되는지 확인하세요.

이 모든 것이 지나치게 복잡해 보입니다."express": "^4.18.1"

const routes: { methods: string[], path: string }[] = [];

const parseRoute = (def) => {
  if (def.route) {
    routes.push({ path: def.route.path, methods: Object.keys(def.route.methods) });
  } else if (def.name === 'router') {
    // nested route (sub router)..
    def.handle.stack.forEach(parseRoute);
  }
}

// loop over and parse routes
app._router.stack.forEach(parseRoute);

console.log(routes);
//{ path: '/', methods: [ 'get' ] },
//{ path: '/healthcheck', methods: [ 'get' ] },
//{ path: '/assets/theme.css', methods: [ 'get' ] },
//...

급행 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)

이건 나한테 효과가 있었어요

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

app._router.stack.function(middleware) {routerRecursion(middleware, router, 'main')}; console.log(routes);

언급URL : https://stackoverflow.com/questions/14934452/how-to-get-all-registered-routes-in-express

반응형