express.jsのapp.useとapp.getの違い


220

私はnode.jsを表現するのが初めてなので、app.useとapp.getの違いを理解できません。両方を使用して情報を送信できるようです。例えば:

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

これと同じようです:

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

1
ルックスあなたは、3つの異なる答えを得たように、すべてのトピックに何かを貢献:)ここでは、関連する質問ですstackoverflow.com/questions/11321635/...
ベンジャミンGruenbaum

はい、すべての良い答え。よろしくお願いします。
Andre Vorobyov 2013年

回答:


219

app.use()ミドルウェアをアプリケーションにバインドするためのものです。これpathは「マウント」または「プレフィックス」パスであり、ミドルウェアを、それで始まる要求されたパスにのみ適用するように制限します。別のアプリケーションを埋め込むために使用することもできます。

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

// ...

/マウント」パスとして指定することにより、でapp.use()始まるすべてのパスに応答します/。これらはすべて、使用されるHTTP動詞に関係なく次のようになります。

  • GET /
  • PUT /foo
  • POST /foo/bar

app.get()一方、Expressのアプリケーションルーティングの一部であり、GETHTTP動詞で要求されたときに特定のルートを照合して処理することを目的としています。

  • GET /

そして、あなたの例の同等のルーティングapp.use()は実際には次のようになります:

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

更新:違いをよりよく示すための試み

を含むルーティングメソッドは、app.get()リクエストへの応答をより正確に調整するのに役立つ便利なメソッドです。また、パラメーターやなどの機能のサポートも追加されますnext('route')

それぞれの中app.get()でへの呼び出しが行われるapp.use()ので、これらすべてをapp.use()直接直接実行できます。しかし、そうすることは、多くの場合、(おそらく不必要に)さまざまな量のボイラープレートコードの再実装を必要とします。

例:

  • 単純な静的ルートの場合:

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

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
  • 同じルートに複数のハンドラがある場合:

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

    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);
    
        // ...
      });
    });
  • パラメータあり:

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

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

注:これらの機能のExpressの実装は、その中に含まれているRouterLayerRoute


3
組み込みアプリについて言及してくれてありがとう。Expressミドルウェアを整理するのにとても便利な方法です。
wprl 2013年

4
app.useは、app.get、app.post、app.putのそれぞれが実行できるすべてのことを実行できますが、その逆はできないと言っても過言ではありませんか?
ngungo 14

6
まだ理解するのは難しい。
Jeb50 2017

1
の用途と目的を理解するのは良いことですが機能の違いを説明するのに優れた人は誰もいません。私が集めることができるものから、すべての.USEハンドラが最初に実行し、任意のパス.USE一致して始まる、指定したパス(すなわち.USE(「/」、...)とに.get(「/ *」とし... )は同じパスに一致します)。私にとっては、可動部分を見ると全体的な概念を理解しやすいです。
snarf

2
この応答が古くて時代遅れであることは注目に値すると思います。私のコメントの日付の時点では、path-to-regexpもう必要ないか、何でもあり、useメソッドの最初の引数でルートパラメータを直接使用できます。
vdegenne 2018

50

app.use Expressが依存するミドルウェアフレームワークであるConnectの「低レベル」メソッドです。

これが私のガイドラインです:

  • app.getGETメソッドを公開する場合に使用します。
  • app.useミドルウェア(Expressで設定したルートに到着する前のHTTPリクエストのハンドラー)を追加する場合、またはルートをモジュール化する場合(たとえば、一連のルートを公開する場合)に使用します。他のWebアプリケーションが使用できるnpmモジュールから)。

しかし、方法を気にしない場合、app.useいくつかのルートを処理するために使用できますか?またはapp.use、ルーティングに使用しないでください。
Elemento0

app.useを使用して、ルートを別のファイルに移動できます。users.js、buildings.js
Rob Angelier、2016年

1
この上の1つの答えはより多くの賛成/賛成を集めましたが、あなたの答えはミドルウェアを含む洗練されたものをいくつかの単純な言葉、工藤に翻訳します。
Jeb50 2017

50

単にapp.useは「すべてのリクエストでこれを実行する」を意味しますapp.getは「
指定されたURLについて、GETリクエストでこれを実行する」を意味します


それはそれほど単純ではありません。他の答えを読んでください。
David Lopez

28

app.getときに呼び出されるHTTPメソッドがに設定されているGETのに対し、app.use関係なく、HTTPメソッドの呼ばれ、したがって、急行パッケージはあなたがにアクセスすることができます他のすべてのRESTfulなタイプの上にある層を定義します。


19

app.use&の違いapp.get

app.use →これは通常、アプリケーションにミドルウェアを導入するために使用され、すべてのタイプのHTTP要求を処理できます。

app.get →GET HTTPリクエストを処理するためだけのものです。

現在、app.use&の間には混乱がありapp.allます。間違いなく、それらにはすべての種類のHTTP要求を処理できるという共通点が1つあります。しかし、ミドルウェアにはapp.useを使用し、ルート処理にはapp.allを使用することを推奨するいくつかの違いがあります。

  1. app.use()→コールバックは1つだけです。
    app.all()→複数のコールバックを受け取ることができます。

  2. app.use()URLが指定されたパスで始まるかどうかのみを確認します。
    しかし、app.all()完全なパスに一致します。

例えば、

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()内部で呼び出してapp.use()次のミドルウェアや任意の経路ハンドラのいずれかを呼び出しますが、next()コールの内部がapp.all()(次のルートハンドラが呼び出されますapp.all()app.get/post/put...のみなど)。後にミドルウェアがある場合はスキップされます。したがって、すべてのミドルウェアを常にルートハンドラーの上に置くことをお勧めします。

1
ポイント3はExpress 4.16には適用されないようです。next()内部で呼び出すapp.all('/*', ...)と、実際app.use('/', ...)にはファイルの後半で実行されます。たぶん、あなたを誤解しました。そうでなければ非常に役立つ説明。
BeetleJuice

4.17では、@ BeetleJuiceと同じことを観察しました
David Lopez

4

上記の説明に加えて、私が経験するもの:

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

URLとして「/ book」で始まるすべてのリクエストに一致します。したがって、「/ book / 1」または「/ book / 2」にも一致します

app.get('/book')  

完全一致の GETリクエストのみに一致します。「/ book / 1」や「/ book / 2」のようなURLは処理しません

したがって、すべてのルートを処理するグローバルハンドラーが必要な場合は、 app.use('/')はがオプションです。app.get('/')ルートURLのみを処理します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.