Diferença entre app.use e app.get no express.js

220

Sou um pouco novo para expressar e node.js, e não consigo descobrir a diferença entre app.use e app.get. Parece que você pode usar os dois para enviar informações. Por exemplo:

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

parece ser o mesmo que isto:

app.get('/', function (req,res) {
   res.send('Hello');
});
Andre Vorobyov
fonte
1
Parece que você tem três respostas diferentes, todos algo a contribuir para o tópico :) Aqui está uma pergunta relacionada stackoverflow.com/questions/11321635/...
Benjamin Gruenbaum
sim, todas as boas respostas. Obrigado, vou dar uma olhada nisso.
Andre Vorobyov 24/03

Respostas:

219

app.use()destina-se a vincular o middleware ao seu aplicativo. O pathé um caminho " mount " ou " prefix " e limita o middleware a aplicar-se apenas a todos os caminhos solicitados que começam com ele. Pode até ser usado para incorporar outro aplicativo:

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

// ...

Ao especificar /como um caminho " mount ", app.use()responderá a qualquer caminho que comece com /, todos eles e independentemente do verbo HTTP usado:

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

app.get(), por outro lado, faz parte do roteamento de aplicativo do Express e destina-se a corresponder e manipular uma rota específica quando solicitado com o GETverbo HTTP:

  • GET /

E, o roteamento equivalente para o seu exemplo app.use()seria:

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

( Atualização: Tentativa de demonstrar melhor as diferenças. )

Os métodos de roteamento, inclusive app.get(), são métodos de conveniência que ajudam a alinhar as respostas às solicitações com mais precisão. Eles também adicionam suporte a recursos como parâmetros e next('route').

Em cada uma delas app.get()há uma chamada para app.use(), assim você certamente pode fazer tudo isso app.use()diretamente. Mas, para isso, muitas vezes será necessário (provavelmente desnecessariamente) reimplementar várias quantidades de código padrão.

Exemplos:

  • Para rotas estáticas simples:

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

    vs.

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
  • Com vários manipuladores para a mesma rota:

    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);
    
        // ...
      });
    });
  • Com 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: implementação destas características Express' estão contidos em sua Router, LayereRoute .

Jonathan Lonowski
fonte
3
Parabéns por mencionar aplicativos incorporados. É uma maneira muito útil de organizar o middleware expresso.
Wprl 24/03
4
É justo dizer que app.use pode fazer tudo que app.get, app.post, app.put faz, mas não vice-versa?
precisa saber é o seguinte
6
ainda difícil de entender.
Jeb50
1
É bom saber o que usar e obter são para , mas ninguém faz um ótimo trabalho de explicar como eles funcionam de forma diferente. Pelo que pude reunir, todos os manipuladores .use são executados primeiro e .use corresponde a qualquer caminho que comece com o caminho especificado (por exemplo, .use ('/', ...) e .get ('/ *', ... ) corresponderia aos mesmos caminhos). Para mim, é mais fácil entender os conceitos gerais quando posso ver as partes móveis.
18718 snarf
2
Acho que é digno de nota que essa resposta é antiga e obsoleta. Na data do meu comentário, você não precisa path-to-regexpmais nada e pode usar parâmetros de rota diretamente no primeiro argumento do usemétodo.
precisa saber é o seguinte
50

app.use é o método de "nível inferior" do Connect, a estrutura de middleware da qual o Express depende.

Aqui está minha orientação:

  • Use app.getse você deseja expor um método GET.
  • Use app.usese você deseja adicionar algum middleware (um manipulador para a solicitação HTTP antes que ela chegue às rotas que você configurou no Express) ou se você deseja modular suas rotas (por exemplo, expor um conjunto de rotas) de um módulo npm que outros aplicativos da web possam usar).
Matthew Ratzloff
fonte
Mas se eu não me importo com o método, posso usar app.usepara lidar com algumas rotas? Ou nunca devemos usar app.usepara roteamento.
Elemento0
Você pode usar app.use para mover suas rotas para arquivos separados eq. users.js, buildings.js
Rob Angelier
1
Embora a resposta acima tenha reunido muito mais ACIMA / ACORDO, sua resposta traduz coisas sofisticadas, incluindo Middleware, em poucas palavras simples, kudo.
precisa saber é o seguinte
50

Simplesmente app.use significa "Executar isso em TODAS as solicitações"
app.get significa "Executar isso em uma solicitação GET, para o URL especificado"

Dhyan Mohandas
fonte
Não é tão simples assim. Leia outras respostas.
David Lopez
28

app.geté chamado quando o método HTTP é definido como GET, enquanto app.useé chamado independentemente do método HTTP e, portanto, define uma camada que está no topo de todos os outros tipos RESTful aos quais os pacotes expressos dão acesso.

MrLore
fonte
19

Diferença entre app.use& app.get:

app.use → Geralmente é usado para introduzir middlewares em sua aplicação e pode lidar com todos os tipos de solicitações HTTP.

app.get → É apenas para lidar com solicitações GET HTTP.

Agora, há uma confusão entre app.use& app.all. Sem dúvida, há uma coisa comum neles, que ambos podem lidar com todos os tipos de solicitações HTTP. Mas existem algumas diferenças que nos recomendam usar app.use para middlewares e app.all para manipulação de rotas.

  1. app.use()→ Leva apenas um retorno de chamada.
    app.all()→ Pode receber vários retornos de chamada.

  2. app.use()verá apenas se o URL inicia com o caminho especificado.
    Mas, app.all()corresponderá ao caminho completo.

Por exemplo,

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()chamar dentro do app.use()vão chamar o próximo middleware ou qualquer manipulador de rota, mas next()chamada dentro app.all()vai chamar o manipulador de rota seguinte ( app.all(), app.get/post/put...etc.) somente. Se houver algum middleware depois, ele será ignorado. Portanto, é aconselhável colocar todos os middlewares sempre acima dos manipuladores de rota.
Ankit Kumar
fonte
1
Seu ponto 3 parece não se aplicar ao Express 4.16. chamar next()dentro de app.all('/*', ...), de fato, executará uma versão app.use('/', ...)posterior no arquivo. Talvez eu tenha te entendido mal lá. Explicação muito útil caso contrário.
BeetleJuice 17/05/19
Em 4.17, observei o mesmo que @BeetleJuice
David Lopez
4

Além das explicações acima, o que eu experimento:

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

corresponderá a todos os pedidos que começam com '/ book' como URL. portanto, também corresponde a '/ book / 1' ou '/ book / 2'

app.get('/book')  

corresponde apenas à solicitação GET com a correspondência exata . Ele não manipula URLs como '/ book / 1' ou '/ book / 2'

Portanto, se você deseja um manipulador global que lide com todas as suas rotas, essa app.use('/')é a opção. app.get('/')manipulará apenas o URL raiz.

Atilla Baspinar
fonte