usando proyecto node cómo crear node.js express

node.js - proyecto - node js express



¿Cómo obtener todas las rutas registradas en Express? (13)

Tengo una aplicación web creada usando Node.js y Express. Ahora me gustaría enumerar todas las rutas registradas con sus métodos apropiados.

Por ejemplo, si he ejecutado

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

Me gustaría recuperar un objeto (o algo equivalente a eso) como:

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

¿Es posible? y si lo es, cómo?

ACTUALIZACIÓN: Mientras tanto, he creado un paquete npm llamado get-routes que extrae las rutas de una aplicación determinada, lo que resuelve este problema. Actualmente, solo se admite Express 4.x, pero supongo que por ahora esto está bien. Solo para tu información.


expreso 3.x

De acuerdo, lo encontré yo mismo ... es solo una aplicación. app.routes :-)

expreso 4.x

Applications - construidas con express()

app._router.stack

Routers - construidos con express.Router()

router.stack

Nota : La pila también incluye las funciones de middleware, debe filtrarse para obtener solo las "rutas" .


Express 4

Dada una configuración de Express 4 con puntos finales y enrutadores anidados

const express = require(''express'') const app = express() const router = express.Router() app.get(...) app.post(...) router.use(...) router.get(...) router.post(...) app.use(router)

Ampliando la respuesta de @caleb es posible obtener todas las rutas recursivamente y ordenadas.

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 }

Para salida de cadena básica.

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 }

Actualización 1:

Debido a las limitaciones internas de Express 4, no es posible recuperar la aplicación montada y los enrutadores montados. Por ejemplo, no es posible obtener rutas desde esta configuración.

const subApp = express() app.use(''/sub/app'', subApp) const subRouter = express.Router() app.use(''/sub/route'', subRouter)


Aquí hay una pequeña cosa que uso solo para obtener las rutas registradas en 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


Copia / pega la respuesta de Hacky cortesía de Doug Wilson sobre los problemas expresos de github . Sucio, pero funciona como un encanto.

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

Produce


En Express 3.5.x, agrego esto antes de iniciar la aplicación para imprimir las rutas en mi terminal:

var routes = app.routes; for (var verb in routes){ if (routes.hasOwnProperty(verb)) { routes[verb].forEach(function(route){ console.log(verb + " : "+route[''path'']); }); } }

Quizás pueda ayudar ...


En Express 4 puede seguir esta útil guía: list-all-rest-endpoints

Lo he adaptado para mis necesidades. He usado express.Router () y registré mis rutas de esta manera:

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

Cambié el nombre del archivo document.js en apiTable.js y lo adapté así:

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

entonces lo llamo en mi server.js de esta manera:

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

El resultado es así:

Es solo un ejemplo, pero podría ser útil ... espero ...


Esto funcionó para mí

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


Esto obtiene las rutas registradas directamente en la aplicación (a través de la aplicación.VERB) y las rutas que están registradas como middleware del enrutador (a través de 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}}


Me inspiré en las rutas de listas expresas de Labithiotis, pero quería una visión general de todas mis rutas y urls brutas de una vez, y no especificar un enrutador, y averiguar el prefijo cada vez. Algo que se me ocurrió fue simplemente reemplazar la función app.use con mi propia función que almacena la baseUrl y el enrutador dado. Desde allí puedo imprimir cualquier tabla de todas mis rutas.

NOTA, esto funciona para mí porque declaro mis rutas en un archivo de rutas específico (función) que se pasa en el objeto de la aplicación, como este:

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

Esto me permite pasar otro objeto ''aplicación'' con una función de uso falso, y puedo obtener TODAS las rutas. Esto funciona para mí (eliminé la comprobación de errores para mayor claridad, pero aún funciona para el ejemplo):

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

Este ejemplo completo (con algunos enrutadores CRUD básicos) acaba de probarse e imprimirse:

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

Usando cli-table obtuve algo como esto:

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

Que patea el culo.


Un enfoque ligeramente actualizado y más funcional para la respuesta de @prranay:

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


Una función para registrar todas las rutas en Express 4 (se puede ajustar fácilmente para 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);

Logs de salida:

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

Hecho esto en un NPM https://www.npmjs.com/package/express-list-routes


https://www.npmjs.com/package/express-list-endpoints funciona bastante bien.

Ejemplo

Uso:

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

Salida:

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


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