Node.js/Express.js: ¿Cómo funciona app.router?

Resuelto Aust asked hace 12 años • 4 respuestas

Antes de preguntar, app.routercreo que debería explicar al menos lo que creo que sucede cuando se trabaja con middleware. Para utilizar middleware, la función a utilizar es app.use(). Cuando se ejecuta el middleware, llamará al siguiente middleware utilizandonext() o hará que no se llame a más middleware. Eso significa que el orden en el que realizo mis llamadas de middleware es importante, porque algunos middleware dependen de otros middleware y es posible que algunos middleware cercanos al final ni siquiera sean llamados.

Hoy estaba trabajando en mi aplicación y tenía mi servidor ejecutándose en segundo plano. Quería hacer algunos cambios, actualizar mi página y ver los cambios inmediatamente. Específicamente, estaba haciendo cambios en mi diseño. No pude hacerlo funcionar, así que busqué la respuesta en Stack Overflow y encontré esta pregunta . Dice que se asegure de que express.static()esté debajo require('stylus'). Pero cuando estaba mirando el código de ese OP, vi que tenía suapp.router llamada al final de sus llamadas de middleware, y traté de descubrir por qué era así.

Cuando creé mi aplicación Express.js (versión 3.0.0rc4), utilicé el comando express app --sessions --css stylusy en mi archivo app.js el código vino configurado con los app.routerdos anteriores express.static()yrequire('stylus') . Entonces parece que, si ya viene configurado de esa manera, entonces debería permanecer así.

Después de reorganizar mi código para poder ver los cambios de mi Stylus, se ve así:

app.configure(function(){
  //app.set() calls
  //app.use() calls
  //...
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});

app.get('/', routes.index);

app.get('/test', function(req, res){
  res.send('Test');
});

Entonces decidí que el primer paso sería descubrir por qué es importante tenerlo app.routeren mi código. Así que lo comenté, inicié mi aplicación y navegué hasta /. Mostró mi página de índice muy bien. Hmm, tal vez funcionó porque estaba exportando la ruta desde mi archivo de rutas (routes.index). Luego navegué /testy mostró Prueba en la pantalla. Jaja, está bien, no tengo idea de qué lo app.routerhace. Ya sea que esté incluido en mi código o no, mi enrutamiento está bien. Entonces definitivamente me estoy perdiendo algo.

Ésta es mi pregunta:

¿Podría alguien explicar qué app.routeres, su importancia y dónde debo colocarlo en mis llamadas de middleware? También sería bueno si recibiera una breve explicación sobre express.static(). Hasta donde puedo decir, express.static()es un caché de mi información, y si la aplicación no puede encontrar la página solicitada, verificará el caché para ver si existe.

Aust avatar Oct 03 '12 00:10 Aust
Aceptado

Nota: Esto describe cómo funcionó Express en las versiones 2 y 3. Consulte el final de esta publicación para obtener información sobre Express 4.


staticsimplemente sirve archivos ( recursos estáticos ) desde el disco. Le asigna una ruta (a veces llamada punto de montaje) y entrega los archivos en esa carpeta.

Por ejemplo, express.static('/var/www')serviría los archivos de esa carpeta. http://server/file.htmlPor lo tanto, serviría una solicitud a su servidor Node /var/www/file.html.

routeres el código que ejecuta tus rutas. Cuando lo hace app.get('/user', function(req, res) { ... });, es el routerque realmente invoca la función de devolución de llamada para procesar la solicitud.

El orden en el que pasa las cosas app.usedetermina el orden en el que cada middleware tiene la oportunidad de procesar una solicitud. Por ejemplo, si tiene un archivo llamado test.htmlen su carpeta estática y una ruta:

app.get('/test.html', function(req, res) {
    res.send('Hello from route handler');
});

¿Cuál se envía a un cliente que lo solicita http://server/test.html? Cualquier middleware que se le dé useprimero.

Si haces esto:

app.use(express.static(__dirname + '/public'));
app.use(app.router);

Luego se entrega el archivo en el disco.

Si lo haces al revés,

app.use(app.router);
app.use(express.static(__dirname + '/public'));

Luego, el controlador de ruta recibe la solicitud y se envía "Hola desde el controlador de ruta" al navegador.

Por lo general, desea colocar el enrutador encima del middleware estático para que un archivo con un nombre accidental no pueda anular una de sus rutas.

Tenga en cuenta que si no uselo hace explícitamente router, Express lo agrega implícitamente en el momento en que define una ruta (razón por la cual sus rutas aún funcionaron aunque haya comentado app.use(app.router)).


Un comentarista mencionó otro punto sobre el orden staticy routerque no había abordado: el impacto en el rendimiento general de su aplicación.

Otra razón para lo use routeranterior statices optimizar el rendimiento. Si pones staticprimero, accederás al disco duro en cada solicitud para ver si existe o no un archivo. En una prueba rápida , descubrí que esta sobrecarga ascendía a ~1 ms en un servidor descargado. (Es muy probable que ese número sea mayor bajo carga, donde las solicitudes competirán por el acceso al disco).

Con routerel primero, una solicitud que coincida con una ruta nunca tiene que llegar al disco, lo que ahorra preciosos milisegundos.

Por supuesto, hay formas de mitigar staticlos gastos generales.

La mejor opción es colocar todos sus recursos estáticos en una carpeta específica. (IE /static) Luego puede montar staticesa ruta para que solo se ejecute cuando la ruta comience con /static:

app.use('/static', express.static(__dirname + '/static'));

En esta situación, pondrías esto arriba router. Esto evita procesar otro middleware/enrutador si hay un archivo presente, pero para ser honesto, dudo que gane tanto.

También puede usar staticCache, que almacena en caché los recursos estáticos en la memoria para que no tenga que acceder al disco para archivos solicitados con frecuencia. ( Advertencia: staticCache aparentemente se eliminará en el futuro).

Sin embargo, no creo que staticCachealmacene en caché las respuestas negativas (cuando un archivo no existe), por lo que no ayuda si lo coloca staticCachearriba routersin montarlo en una ruta.

Al igual que con todas las preguntas sobre rendimiento, mida y compare su aplicación del mundo real (bajo carga) para ver dónde están realmente los cuellos de botella.


expreso 4

Express 4.0 elimina app.router . Todo el middleware ( app.use) y las rutas ( app.getet al) ahora se procesan precisamente en el orden en que se agregan.

En otras palabras:

Todos los métodos de enrutamiento se agregarán en el orden en que aparecen. No deberías hacerlo app.use(app.router). Esto elimina el problema más común con Express.

En otras palabras, mezclar app.use()y app[VERB]()funcionará exactamente en el orden en que se llaman.

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

Lea más sobre los cambios en Express 4.

josh3736 avatar Oct 02 '2012 18:10 josh3736

Enrutamiento significa determinar cómo responde una aplicación a una solicitud de un cliente a un punto final particular, que es un URI (o ruta) y un método de solicitud HTTP específico (GET, POST, etc.). Cada ruta puede tener una o más funciones de controlador, que se ejecutan cuando la ruta coincide.

En Express 4.0 Router, tenemos más flexibilidad que nunca para definir nuestras rutas.

express.Router() se usa varias veces para definir grupos de rutas.

ruta utilizada como middleware para procesar solicitudes.

ruta utilizada como middleware para validar parámetros usando ".param()".

app.route() se utiliza como acceso directo al enrutador para definir múltiples solicitudes en una ruta

cuando usamos app.route(), conectamos nuestra aplicación con ese enrutador.

var express = require('express'); //used as middleware
var app = express(); //instance of express.
app.use(app.router);
app.use(express.static(__dirname + '/public')); //All Static like [css,js,images] files are coming from public folder
app.set('views',__dirname + '/views'); //To set Views
app.set('view engine', 'ejs'); //sets View-Engine as ejs
app.engine('html', require('ejs').renderFile); //actually rendering HTML files through EJS. 
app.get('/', function (req, res) {
  res.render('index');  
})
app.get('/test', function (req, res) {
  res.send('test')
})
Parth Raval avatar Nov 04 '2016 17:11 Parth Raval