Perbedaan antara app.use dan app.get di express.js

220

Saya agak baru untuk mengekspresikan dan node.js, dan saya tidak tahu perbedaan antara app.use dan app.get. Sepertinya Anda dapat menggunakan keduanya untuk mengirim informasi. Sebagai contoh:

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

tampaknya sama dengan ini:

app.get('/', function (req,res) {
   res.send('Hello');
});
Andre Vorobyov
sumber
1
Sepertinya Anda mendapat tiga jawaban berbeda, semuanya menyumbangkan sesuatu untuk topik ini :) Berikut adalah pertanyaan terkait stackoverflow.com/questions/11321635/…
Benjamin Gruenbaum
ya, semua jawaban bagus. Terima kasih, saya akan melihatnya.
Andre Vorobyov

Jawaban:

219

app.use()dimaksudkan untuk mengikat middleware ke aplikasi Anda. Ini pathadalah jalur " mount " atau " awalan " dan membatasi middleware hanya berlaku untuk jalur apa pun yang diminta yang dimulai dengan itu. Ia bahkan dapat digunakan untuk menyematkan aplikasi lain:

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

// ...

Dengan menetapkan /sebagai jalur " mount ", app.use()akan merespons ke setiap jalur yang dimulai /, yang semuanya dan terlepas dari kata kerja HTTP yang digunakan:

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

app.get(), di sisi lain, adalah bagian dari perutean aplikasi Express dan dimaksudkan untuk mencocokkan dan menangani rute tertentu ketika diminta dengan GETkata kerja HTTP:

  • GET /

Dan, perutean yang setara untuk contoh Anda app.use()sebenarnya adalah:

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

( Pembaruan: Berusaha untuk lebih menunjukkan perbedaan. )

Metode perutean, termasuk app.get(), adalah metode praktis yang membantu Anda menyelaraskan respons terhadap permintaan dengan lebih tepat. Mereka juga menambahkan dukungan untuk fitur seperti parameter dan next('route').

Dalam setiap app.get()panggilan app.use(), jadi Anda pasti bisa melakukan semua ini dengan app.use()langsung. Tetapi, melakukan hal itu akan sering membutuhkan (mungkin tidak perlu) menerapkan kembali sejumlah kode boilerplate.

Contoh:

  • Untuk rute sederhana dan statis:

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

    vs.

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
  • Dengan beberapa penangan untuk rute yang sama:

    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);
    
        // ...
      });
    });
  • Dengan parameter:

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

Catatan: Pelaksanaan Express' fitur ini terkandung dalam nya Router, LayerdanRoute .

Jonathan Lonowski
sumber
3
Kudos untuk menyebutkan aplikasi yang disematkan. Ini adalah cara yang sangat berguna untuk mengatur middleware ekspres.
wprl
4
Apakah adil untuk mengatakan bahwa app.use dapat melakukan semuanya di app.get, app.post, app.put tetapi tidak sebaliknya?
ngungo
6
masih sulit dimengerti.
Jeb50
1
Itu baik untuk mengetahui apa yang digunakan dan dapatkan adalah untuk , tetapi tidak ada yang melakukan pekerjaan yang besar menjelaskan bagaimana mereka berfungsi secara berbeda. Dari apa yang saya dapat kumpulkan, semua penangan .use dijalankan terlebih dahulu, dan .use cocok dengan semua jalur yang dimulai dengan jalur yang ditentukan (yaitu .use ('/', ...) dan .get ('/ *', ... ) akan cocok dengan jalur yang sama). Bagi saya lebih mudah untuk memahami konsep keseluruhan ketika saya bisa melihat bagian yang bergerak.
snarf
2
Saya pikir ini SANGAT MENCARI bahwa respons ini sudah tua dan usang, pada tanggal komentar saya Anda tidak perlu path-to-regexpatau apa pun lagi dan Anda dapat menggunakan parameter rute secara langsung dalam argumen pertama usemetode ini.
vdegenne
50

app.use adalah metode "tingkat lebih rendah" dari Connect, kerangka kerja middleware tempat Express bergantung.

Inilah panduan saya:

  • Gunakan app.getjika Anda ingin mengekspos metode GET.
  • Gunakan app.usejika Anda ingin menambahkan beberapa middleware (penangan untuk permintaan HTTP sebelum sampai ke rute yang Anda atur di Express), atau jika Anda ingin membuat rute Anda modular (misalnya, memperlihatkan serangkaian rute dari modul npm yang dapat digunakan aplikasi web lain).
Matthew Ratzloff
sumber
Tetapi jika saya tidak peduli dengan metode ini, saya dapat menggunakan app.useuntuk menangani beberapa rute? Atau kita tidak boleh menggunakan app.useuntuk routing.
Elemento0
Anda dapat menggunakan app.use untuk memindahkan rute Anda ke memisahkan file eq. users.js, buildings.js
Rob Angelier
1
walaupun satu jawaban di atas ini telah mengumpulkan lebih banyak UP / SETUJU, jawaban Anda menerjemahkan hal-hal canggih termasuk Middleware menjadi beberapa kata sederhana, kudo.
Jeb50
50

Cukup app.use berarti "Jalankan ini di SEMUA permintaan"
app.get berarti "Jalankan ini pada permintaan GET, untuk URL yang diberikan"

Dhyan Mohandas
sumber
Tidak sesederhana itu. Baca jawaban lain.
David Lopez
28

app.getdipanggil ketika metode HTTP diatur ke GET, sedangkan app.usedipanggil terlepas dari metode HTTP, dan oleh karena itu mendefinisikan lapisan yang di atas semua jenis RESTful lain yang paket ekspres memberi Anda akses.

TuanLore
sumber
19

Perbedaan antara app.use& app.get:

app.use → Ini umumnya digunakan untuk memperkenalkan middlewares di aplikasi Anda dan dapat menangani semua jenis permintaan HTTP.

app.get → Ini hanya untuk menangani MENDAPATKAN permintaan HTTP.

Sekarang, ada kebingungan antara app.use& app.all. Tidak diragukan lagi, ada satu hal yang sama di dalamnya, yaitu keduanya dapat menangani semua jenis permintaan HTTP. Tetapi ada beberapa perbedaan yang merekomendasikan kita untuk menggunakan app.use untuk middlewares dan app.all untuk penanganan rute.

  1. app.use()→ Hanya membutuhkan satu panggilan balik.
    app.all()→ Dapat mengambil beberapa panggilan balik.

  2. app.use()hanya akan melihat apakah url dimulai dengan jalur yang ditentukan.
    Tapi, app.all()akan cocok dengan path lengkapnya.

Sebagai contoh,

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()panggilan di dalam app.use()akan memanggil middleware berikutnya atau pengendali rute apa pun, tetapi next()panggilan di dalam hanya app.all()akan memanggil pengendali rute berikutnya ( app.all(), app.get/post/put...dll.) saja. Jika ada middleware setelahnya, itu akan dilewati. Jadi, disarankan untuk meletakkan semua middlewares selalu di atas penangan rute.
Ankit Kumar
sumber
1
Poin 3 Anda tampaknya tidak berlaku pada Express 4.16. menelepon next()di app.all('/*', ...)dalam sebenarnya akan menjalankan app.use('/', ...)nanti dalam file. Mungkin saya salah paham dengan Anda di sana. Penjelasan yang sangat membantu sebaliknya.
BeetleJuice
Di 4.17 saya mengamati hal yang sama dengan @BeetleJuice
David Lopez
4

Selain penjelasan di atas, apa yang saya alami:

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

akan cocok dengan semua permintaan yang dimulai dengan '/ buku' sebagai URL. jadi itu juga cocok dengan '/ book / 1' atau '/ book / 2'

app.get('/book')  

hanya cocok MENDAPATKAN permintaan dengan kecocokan persis . Ini tidak akan menangani URL seperti '/ book / 1' atau '/ book / 2'

Jadi, jika Anda menginginkan penangan global yang menangani semua rute Anda, maka app.use('/')adalah pilihannya. app.get('/')hanya akan menangani URL root.

Atilla Baspinar
sumber