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


181

Tengo una aplicación web creada con 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.


Todas las soluciones que probé no funcionan cuando tienes enrutadores definidos. Solo funciona por ruta, lo que no me da la URL completa de esa ruta en mi aplicación ...
guy mograbi

1
@guymograbi es posible que desee mirar stackoverflow.com/a/55589657/6693775
nbsamar

Respuestas:


230

expreso 3.x

Bien, lo encontré yo mismo ... es solo app.routes :-)

expreso 4.x

Aplicaciones : construidas conexpress()

app._router.stack

Enrutadores : construidos conexpress.Router()

router.stack

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


Estoy usando el nodo 0.10 y fue app.routes.routes, lo que significa que podía hacer JSON.stringify (app.routes.routes)
guy mograbi

77
Solo funciona para Express 3.x, no 4.x. En 4.x, debe verificarapp._router.stack
avetisk

14
Esto no funcionó como se esperaba para mí. app._router no parece incluir rutas desde app.use ('/ path', otherRouter);
Michael Cole

¿Hay alguna manera de que esto pueda integrarse con un script de línea de comandos que extraiga exactamente los mismos archivos de ruta que la aplicación en vivo sin realmente iniciar una aplicación web?
Lawrence I. Siden

55
Al menos en express 4.13.1 app._router.stackno está definido.
levigroker

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

1
Tenga en cuenta que si está utilizando algo como Express Router (u otro middleware), debería ver @Caleb una respuesta un poco más larga que se expande en este enfoque.
Iain Collins

31

Esto obtiene rutas registradas directamente en la aplicación (a través de app.VERB) y rutas 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}}

1
Excelente, gracias por un ejemplo que muestra cómo configurar las rutas de visualización a través de middleware como el enrutador Express.
Iain Collins

31

He adaptado una publicación anterior que ya no está en línea para mis necesidades. Utilicé 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 así:

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

El resultado se ve así:

Ejemplo de resultado

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


2
Esto no funciona para rutas anidadas como se identifica aquí: stackoverflow.com/questions/25260818/…

2
¡Cuidado con el enlace en esta respuesta! Me redirigió a un sitio web aleatorio y forzó una descarga a mi computadora.
Tyler Bell

29

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

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

¿dónde pones esto, en app.js ??
Juan

21

DEBUG=express:* node index.js

Si ejecuta su aplicación con el comando anterior, iniciará su aplicación con DEBUG módulo y le dará rutas, además de todas las funciones de middleware que están en uso.

Puede consultar: ExpressJS: depuración y depuración .


3
Con mucho, la mejor respuesta ... ¡una env var!
Jeef

De hecho, la respuesta más útil. @nbsamar Incluso puede expandirlo para decir que se use solo DEBUG=express:pathspara ver la salida de la ruta y no todos los demás mensajes de depuración. ¡Gracias!
Mark Edington

19

Hacky copiar / pegar respuesta cortesía de Doug Wilson sobre los problemas express 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

captura de pantalla


¿Por qué las rutas no son distintas?
Vladimir Vukanac

1
Este es el único que me funcionó con Express 4.15. Ninguno de los otros dio el camino completo. La única advertencia es que no devuelve la ruta raíz predeterminada / ninguno de ellos lo hace.
Shane

No entiendo por qué atas argumentos print?
ZzZombo

@ZzZombo pregunta a Doug Wilson, él lo escribió. Probablemente puedas limpiar todo esto si quieres.
AlienWebguy

11

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

2
Esto no funciona con: server = express(); app1 = express(); server.use('/app1', app1); ...
Danosaure

8

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

Salida de registros:

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

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


1
Esto no funcionó como se esperaba para mí. app._router no parece incluir rutas desde app.use ('/ path', otherRouter);
Michael Cole

@MichaelCole ¿Viste la respuesta a continuación de Golo Roden?
Labithiotis

@ Dazzler13 Jugué con esto durante una hora y no pude hacerlo funcionar. Express 4.0. La aplicación creada, el enrutador realizado, la aplicación.use (ruta, enrutador), las rutas del enrutador no aparecieron en la aplicación. ¿Ejemplo?
Michael Cole

El ejemplo de @Caleb a continuación funciona bien para rutas manejadas con algo como express.Router si ese es tu problema. Tenga en cuenta que las rutas configuradas con middleware (incluido express.Router) pueden no aparecer de inmediato y es posible que deba agregar un breve retraso antes de verificarlas en app._router (incluso utilizando el enfoque de @Caleb).
Iain Collins

8

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

Se ve como esto:

[
  {
    "method": "GET",
    "path": "/api/todos"
  },
  {
    "method": "POST",
    "path": "/api/todos"
  },
  {
    "method": "PUT",
    "path": "/api/todos/:id"
  },
  {
    "method": "DELETE",
    "path": "/api/todos/:id"
  }
]

salida de cadena

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

Se ve como esto:

GET    /api/todos  
POST   /api/todos  
PUT    /api/todos/:id  
DELETE /api/todos/:id

estos se basan en la respuesta de @ corvid

espero que esto ayude


5

Me inspiré en la lista de rutas expresas de Labithiotis, pero quería una visión general de todas mis rutas y urls brutas de una sola vez, y no especificar un enrutador, y calcular 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, así:

// 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ó algunos errores de comprobación de 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) se acaba de probar e imprimir:

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

Lo que patea traseros.


4

Expreso 4

Dada una configuración 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 @caleb es posible obtener todas las rutas de forma recursiva 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)

Salida de la consola

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

Listado de rutas montadas funciona con este paquete: github.com/AlbertoFdzM/express-list-endpoints
jsaddwater

4

Necesita algunos ajustes, pero debería funcionar para Express v4. Incluyendo esas rutas agregadas con .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", "..."]

editar: mejoras de código


3

Enfoque ligeramente actualizado y más funcional a 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));

2

Esto funciono para mi

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

2

Inicializar enrutador express

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!',
      });
   });   

Importar controlador de usuario

var userController = require('./controller/userController');

Rutas de usuario

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

Exportar rutas API

module.exports = router;

Salida

{"status":"API Its Working, APP Route","route": 
[{"path":"/","methods":{"get":true}}, 
{"path":"/users","methods":{"get":true,"post":true}}, 
{"path":"/users/:user_id","methods": ....}

1

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

Tal vez pueda ayudar ...


1

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

Aquí hay una demostración: https://glitch.com/edit/#!/get-all-routes-in-nodejs


0

Así que estaba mirando todas las respuestas ... no me gustó la mayoría ... tomé algunas de algunas ... hice esto:

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

no el más bonito ... pero anidado, y hace el truco

También tenga en cuenta el 20 allí ... Supongo que no habrá una ruta normal con 20 métodos ... así que deduzco que es todo ...


0

los detalles de la ruta incluyen la ruta de "express": "4.xx",

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

SALIDA SIMPLE DEL CÓDIGO

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

0

Simplemente use este paquete npm, dará la salida web y la salida del terminal en una buena vista de tabla formateada.

ingrese la descripción de la imagen aquí

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


2
Este otro paquete tiene mucha más aceptación. npmjs.com/package/express-list-endpoints . Tengo 21.111 contra 34 descargas semanales. Sin embargo, express-routes-cataloguetambién muestra las rutas como HTML, aunque el otro no.
mayid

1
no está mal, la documentación del paquete difiere del nombre real del paquete cuando se requiere y este paquete, como todos los demás mencionados, solo muestra rutas de una sola capa donde está incluido
hamza khan

@hamzakhan ps gracias por la actualización. Soy el autor, pronto se actualizará en la documentación.
Vijay

-1

Aquí hay una función de una línea para imprimir bonitas las rutas en un Express app:

const getAppRoutes = (app) => app._router.stack.reduce(
  (acc, val) => acc.concat(
    val.route ? [val.route.path] :
      val.name === "router" ? val.handle.stack.filter(
        x => x.route).map(
          x => val.regexp.toString().match(/\/[a-z]+/)[0] + (
            x.route.path === '/' ? '' : x.route.path)) : []) , []).sort();

-2

Publiqué un paquete que imprime todo el middleware así como las rutas, realmente útil cuando intento auditar una aplicación express. Monta el paquete como middleware, por lo que incluso se imprime solo:

https://github.com/ErisDS/middleware-stack-printer

Imprime una especie de árbol como:

- middleware 1
- middleware 2
- Route /thing/
- - middleware 3
- - controller (HTTP VERB)  
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.