Diferencia entre app.use y app.get en express.js

220

Soy un poco nuevo en express y node.js, y no puedo entender la diferencia entre app.use y app.get. Parece que puede usar ambos para enviar información. Por ejemplo:

app.use('/',function(req, res,next) {
    res.send('Hello');
    next();
});

parece ser lo mismo que esto:

app.get('/', function (req,res) {
   res.send('Hello');
});
Andre Vorobyov
fuente
1
Parece que obtuvo tres respuestas diferentes, todas contribuyendo algo al tema :) Aquí hay una pregunta relacionada stackoverflow.com/questions/11321635/…
Benjamin Gruenbaum
Sí, todas buenas respuestas. Gracias, echaré un vistazo a eso.
Andre Vorobyov

Respuestas:

219

app.use()está destinado a vincular middleware a su aplicación. El pathes una ruta de " montaje " o " prefijo " y limita el middleware para que solo se aplique a las rutas solicitadas que comienzan con él. Incluso se puede usar para incrustar otra aplicación:

// subapp.js
var express = require('express');
var app = modules.exports = express();
// ...
// server.js
var express = require('express');
var app = express();

app.use('/subapp', require('./subapp'));

// ...

Al especificar /como una ruta de " montaje ", app.use()responderá a cualquier ruta que comience /, que son todas e independientemente del verbo HTTP utilizado:

  • GET /
  • PUT /foo
  • POST /foo/bar
  • etc.

app.get(), por otro lado, es parte del enrutamiento de la aplicación Express y está destinado a hacer coincidir y manejar una ruta específica cuando se solicita con el GETverbo HTTP:

  • GET /

Y, el enrutamiento equivalente para su ejemplo de app.use()realidad sería:

app.all(/^\/.*/, function (req, res) {
    res.send('Hello');
});

( Actualización: Intentando demostrar mejor las diferencias ) .

Los métodos de enrutamiento, incluidos app.get(), son métodos convenientes que lo ayudan a alinear las respuestas a las solicitudes con mayor precisión. También agregan soporte para características como parámetros y next('route').

Dentro de cada uno app.get()hay una llamada a app.use(), por lo que ciertamente puede hacer todo esto app.use()directamente. Pero hacerlo requerirá a menudo (probablemente innecesariamente) reimplementar varias cantidades de código repetitivo.

Ejemplos:

  • Para rutas simples y estáticas:

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

    vs.

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
  • Con múltiples controladores para la misma ruta:

    app.get('/', authorize('ADMIN'), function (req, res) {
      // ...
    });

    vs.

    const authorizeAdmin = authorize('ADMIN');
    
    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      authorizeAdmin(req, res, function (err) {
        if (err) return next(err);
    
        // ...
      });
    });
  • Con parámetros:

    app.get('/item/:id', function (req, res) {
      let id = req.params.id;
      // ...
    });

    vs.

    const pathToRegExp = require('path-to-regexp');
    
    function prepareParams(matches, pathKeys, previousParams) {
      var params = previousParams || {};
    
      // TODO: support repeating keys...
      matches.slice(1).forEach(function (segment, index) {
        let { name } = pathKeys[index];
        params[name] = segment;
      });
    
      return params;
    }
    
    const itemIdKeys = [];
    const itemIdPattern = pathToRegExp('/item/:id', itemIdKeys);
    
    app.use('/', function (req, res, next) {
      if (req.method !== 'GET') return next();
    
      var urlMatch = itemIdPattern.exec(req.url);
      if (!urlMatch) return next();
    
      if (itemIdKeys && itemIdKeys.length)
        req.params = prepareParams(urlMatch, itemIdKeys, req.params);
    
      let id = req.params.id;
      // ...
    });

Nota: la aplicación de estas características Express están contenidos en su Router, LayeryRoute .

Jonathan Lonowski
fuente
3
Felicitaciones por mencionar aplicaciones integradas. Es una forma muy práctica de organizar el middleware express.
wprl
44
¿Es justo decir que app.use puede hacer todo lo que app.get, app.post, app.put hace pero no al revés?
ngungo
66
Aún es difícil de entender.
Jeb50
1
Es bueno saber qué uso y dan son para , pero nadie hace un gran trabajo de explicar la forma en que funcionan de manera diferente. Por lo que puedo reunir, todos los controladores .use se ejecutan primero, y .use coincide con cualquier ruta que comience con la ruta especificada (es decir .use ('/', ...) y .get ('/ *', ... ) coincidiría con los mismos caminos). Para mí es más fácil entender los conceptos generales cuando puedo ver las partes móviles.
snarf
2
Creo que vale la pena TENER EN CUENTA que esta respuesta es antigua y obsoleta, a partir de la fecha de mi comentario que ya no necesita path-to-regexpni nada, y puede usar parámetros de ruta directamente en el primer argumento del usemétodo.
vdegenne
50

app.use es el método de "nivel inferior" de Connect, el marco de middleware del que Express depende.

Aquí está mi guía:

  • Úselo app.getsi desea exponer un método GET.
  • Úselo app.usesi desea agregar algún middleware (un controlador para la solicitud HTTP antes de que llegue a las rutas que ha configurado en Express), o si desea que sus rutas sean modulares (por ejemplo, exponga un conjunto de rutas desde un módulo npm que otras aplicaciones web podrían usar).
Matthew Ratzloff
fuente
Pero si no me importa el método, ¿puedo usarlo app.usepara manejar algunas rutas? O nunca deberíamos usar app.usepara el enrutamiento.
Elemento0
Puede usar app.use para mover sus rutas para separar archivos eq. users.js, buildings.js
Rob Angelier
1
aunque la respuesta anterior a esto ha reunido mucho más UP / AGREE, su respuesta traduce algo sofisticado que incluye Middleware en unas pocas palabras simples, kudo.
Jeb50
50

Simplemente app.use significa "Ejecutar esto en TODAS las solicitudes"
app.get significa "Ejecutar esto en una solicitud GET, para la URL dada"

Dhyan Mohandas
fuente
No es tan simple. Lee otras respuestas.
David Lopez
28

app.getse llama cuando el método HTTP se establece en GET, mientras que app.usese llama independientemente del método HTTP y, por lo tanto, define una capa que está por encima de todos los otros tipos RESTful a los que los paquetes express le dan acceso.

MrLore
fuente
19

Diferencia entre app.use& app.get:

app.use → Generalmente se usa para introducir middlewares en su aplicación y puede manejar todo tipo de solicitudes HTTP.

app.get → Es solo para manejar solicitudes GET HTTP.

Ahora, hay una confusión entre app.use& app.all. Sin duda, hay una cosa común en ellos, que ambos pueden manejar todo tipo de solicitudes HTTP. Pero hay algunas diferencias que nos recomiendan usar app.use para middlewares y app.all para el manejo de rutas.

  1. app.use()→ Solo se necesita una devolución de llamada.
    app.all()→ Puede tomar múltiples devoluciones de llamada.

  2. app.use()solo verá si la url comienza con la ruta especificada.
    Pero, app.all()coincidirá con la ruta completa.

Por ejemplo,

app.use( "/book" , middleware);
// will match /book
// will match /book/author
// will match /book/subject

app.all( "/book" , handler);
// will match /book
// won't match /book/author   
// won't match /book/subject    

app.all( "/book/*" , handler);
// won't match /book        
// will match /book/author
// will match /book/subject
  1. next()llamar al interior app.use()llamará al siguiente middleware o a cualquier controlador de ruta, pero next()llamar al interior app.all()invocará únicamente al siguiente controlador de ruta ( app.all(), app.get/post/put...etc.). Si hay algún middleware después, se omitirá. Por lo tanto, es recomendable colocar todos los middlewares siempre por encima de los controladores de ruta.
Ankit Kumar
fuente
1
Su punto 3 no parece aplicarse en Express 4.16. llamar next()dentro de app.all('/*', ...)will de hecho ejecutará una app.use('/', ...)posterior en el archivo. Tal vez te entendí mal allí. Muy útil explicación de lo contrario.
BeetleJuice
En 4.17 observé lo mismo que @BeetleJuice
David Lopez
4

Además de las explicaciones anteriores, lo que experimento:

app.use('/book', handler);  

coincidirá con todas las solicitudes que comiencen con '/ book' como URL. entonces también coincide con '/ book / 1' o '/ book / 2'

app.get('/book')  

solo coincide con la solicitud GET con la coincidencia exacta . No manejará URL como '/ book / 1' o '/ book / 2'

Entonces, si desea un controlador global que maneje todas sus rutas, entonces esa app.use('/')es la opción. app.get('/')manejará solo la URL raíz.

Atilla Baspinar
fuente