Différence entre app.use et app.get dans express.js

220

Je suis un peu nouveau pour exprimer et node.js, et je ne peux pas comprendre la différence entre app.use et app.get. Il semble que vous puissiez utiliser les deux pour envoyer des informations. Par exemple:

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

semble être le même que celui-ci:

app.get('/', function (req,res) {
   res.send('Hello');
});
Andre Vorobyov
la source
1
On dirait que vous avez obtenu trois réponses différentes, toutes contribuant au sujet :) Voici une question connexe stackoverflow.com/questions/11321635/…
Benjamin Gruenbaum
oui, toutes les bonnes réponses. Merci, je vais y jeter un œil.
Andre Vorobyov

Réponses:

219

app.use()est destiné à lier le middleware à votre application. Il paths'agit d'un chemin de « montage » ou de « préfixe » et limite le middleware à ne s'appliquer qu'aux chemins demandés qui commencent par lui. Il peut même être utilisé pour intégrer une autre application:

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

// ...

En spécifiant /comme chemin de « montage », app.use()répondra à tout chemin commençant par /, qui sont tous et indépendamment du verbe HTTP utilisé:

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

app.get(), d'autre part, fait partie du routage d'application d'Express et est destiné à faire correspondre et à gérer un itinéraire spécifique lorsque demandé avec le GETverbe HTTP:

  • GET /

Et, le routage équivalent pour votre exemple app.use()serait en fait:

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

( Mise à jour: Tenter de mieux démontrer les différences. )

Les méthodes de routage, notamment app.get(), sont des méthodes pratiques qui vous aident à aligner plus précisément les réponses aux demandes. Ils ajoutent également la prise en charge de fonctionnalités telles que les paramètres et next('route').

Dans chacun d'eux se app.get()trouve un appel à app.use(), donc vous pouvez certainement faire tout cela app.use()directement. Mais cela nécessitera souvent (probablement inutilement) la réimplémentation de diverses quantités de code passe-partout.

Exemples:

  • Pour les itinéraires simples et statiques:

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

    contre.

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
    
  • Avec plusieurs gestionnaires pour le même itinéraire:

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

    contre.

    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);
    
        // ...
      });
    });
    
  • Avec paramètres:

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

    contre.

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

Note: La mise en œuvre d'Express de ces caractéristiques sont contenues dans son Router, LayeretRoute .

Jonathan Lonowski
la source
3
Félicitations pour avoir mentionné les applications intégrées. C'est un moyen très pratique d'organiser un middleware express.
wprl
4
Est-il juste de dire que app.use peut faire tout ce que font app.get, app.post, app.put mais pas l'inverse?
ngungo
6
encore difficile à comprendre.
Jeb50
1
Il est bon de savoir quoi et obtenir sont pour , mais personne ne fait un excellent travail d'expliquer comment ils fonctionnent différemment. D'après ce que je peux comprendre, tous les gestionnaires .use s'exécutent en premier et .use correspond à tout chemin commençant par le chemin spécifié (c'est-à-dire .use ('/', ...) et .get ('/ *', ... ) correspondrait aux mêmes chemins). Pour moi, il est plus facile de comprendre les concepts généraux lorsque je peux voir les pièces mobiles.
snarf
2
Je pense qu'il vaut la peine de noter que cette réponse est ancienne et obsolète, à la date de mon commentaire, vous n'avez plus besoin de path-to-regexprien et vous pouvez utiliser les paramètres de route directement dans le premier argument de la useméthode.
vdegenne
50

app.use est la méthode "de niveau inférieur" de Connect, le framework middleware dont Express dépend.

Voici ma ligne directrice:

  • À utiliser app.getsi vous souhaitez exposer une méthode GET.
  • À utiliser app.usesi vous souhaitez ajouter un middleware (un gestionnaire pour la demande HTTP avant qu'elle n'arrive aux routes que vous avez configurées dans Express), ou si vous souhaitez rendre vos routes modulaires (par exemple, exposer un ensemble de routes à partir d'un module npm que d'autres applications Web pourraient utiliser).
Matthew Ratzloff
la source
Mais si je ne me soucie pas de la méthode, je peux utiliser app.usepour gérer certains itinéraires? Ou nous ne devrions jamais utiliser app.usepour le routage.
Elemento0
Vous pouvez utiliser app.use pour déplacer vos itinéraires vers des fichiers séparés eq. users.js, buildings.js
Rob Angelier
1
bien que la seule réponse ci-dessus ait rassemblé beaucoup plus UP / AGREE, votre réponse traduit une chose sophistiquée, y compris Middleware, en quelques mots simples, bravo.
Jeb50
50

App.use signifie simplement «Exécuter ceci sur TOUTES les demandes»
app.get signifie «Exécuter ceci sur une demande GET, pour l'URL donnée»

Dhyan Mohandas
la source
Ce n'est pas aussi simple. Lisez d'autres réponses.
David Lopez
28

app.getest appelé lorsque la méthode HTTP est définie sur GET, tandis qu'il app.useest appelé quelle que soit la méthode HTTP, et définit donc une couche qui se trouve au-dessus de tous les autres types RESTful auxquels les packages express vous donnent accès.

MrLore
la source
19

Différence entre app.use& app.get:

app.use → Il est généralement utilisé pour introduire des middlewares dans votre application et peut gérer tout type de requêtes HTTP.

app.get → C'est uniquement pour gérer les requêtes HTTP GET.

Maintenant, il y a une confusion entre app.use& app.all. Sans aucun doute, il y a une chose commune en eux, que les deux peuvent gérer toutes sortes de requêtes HTTP. Mais il existe certaines différences qui nous recommandent d'utiliser app.use pour les middlewares et app.all pour la gestion des itinéraires.

  1. app.use()→ Cela ne prend qu'un seul rappel.
    app.all()→ Cela peut prendre plusieurs rappels.

  2. app.use()ne verra que si l'url commence par le chemin spécifié.
    Mais, app.all()correspondra au chemin complet.

Par exemple,

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()call inside app.use()va appeler soit le middleware suivant, soit n'importe quel gestionnaire de route, mais next()call inside app.all()invoquera uniquement le prochain gestionnaire de route ( app.all(), app.get/post/put...etc.). S'il y a un middleware après, il sera ignoré. Il est donc conseillé de placer tous les middlewares toujours au-dessus des gestionnaires d'itinéraire.
Ankit Kumar
la source
1
Votre point 3 ne semble pas s'appliquer à Express 4.16. appeler next()à l' intérieur de app.all('/*', ...)va en fait exécuter une version app.use('/', ...)ultérieure du fichier. Peut-être que je vous ai mal compris là-bas. Explication très utile sinon.
BeetleJuice
En 4.17, j'ai observé la même chose que @BeetleJuice
David Lopez
4

En plus des explications ci-dessus, ce que je vis:

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

correspondra à toutes les demandes commençant par '/ book' comme URL. il correspond donc également à '/ book / 1' ou '/ book / 2'

app.get('/book')  

correspond uniquement à la demande GET avec correspondance exacte . Il ne gérera pas les URL comme '/ book / 1' ou '/ book / 2'

Donc, si vous voulez un gestionnaire global qui gère tous vos itinéraires, app.use('/')c'est l'option. app.get('/')gérera uniquement l'URL racine.

Atilla Baspinar
la source