Node.js / Express.js - How does app.router work? Ask Question

Node.js / Express.js - How does app.router work? Ask Question

Before I ask about app.router I think I should explain at least what I think happens when working with middleware. To use middleware, the function to use is app.use(). When the middleware is being executed, it will either call the next middleware by using next() or make it so no more middleware get called. That means that the order in which I place my middleware calls is important, because some middleware depends on other middleware, and some middleware near the end might not even be called.

Today I was working on my application and had my server running in the background. I wanted to make some changes and refresh my page and see the changes immediately. Specifically, I was making changes to my layout. I couldn't get it to work so I searched Stack Overflow for the answer and found this question. It says to make sure that express.static() is beneath require('stylus'). But when I was looking at that OP's code, I saw that he had his app.router call at the very end of his middleware calls, and I tried to figure out why that was.

When I made my Express.js application (version 3.0.0rc4), I used the command express app --sessions --css stylus and in my app.js file the code came setup with my app.router above both the express.static() and require('stylus') calls. So it seems like, if it comes already setup that way, then it should stay that way.

After re-arranging my code so I could see my Stylus changes, it looks like this:

app.configure(function(){
  //app.set() calls
  //app.use() calls
  //...
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});

app.get('/', routes.index);

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

So I decided that the first step would be to find out why it is important to even have app.router in my code. So I commented it out, started my app and navigated to /. It displayed my index page just fine. Hmm, maybe it worked because I was exporting the routing from my routes file (routes.index). So next I navigated to /test and it displayed Test on the screen. Haha, OK, I have no idea what app.router does. Whether it is included in my code or not, my routing is fine. So I am definitely missing something.

So Here Is My Question:

Could somebody please explain what app.router does, the importance of it, and where I should place it in my middleware calls? It would also be nice if I got a brief explanation about express.static(). As far as I can tell, express.static() is a cache of my information, and if the application can't find the requested page, it will check the cache to see if it exists.

ベストアンサー1

Note: This describes how Express worked in versions 2 and 3. See the end of this post for information about Express 4.


static simply serves files (static resources) from disk. You give it a path (sometimes called the mount point), and it serves the files in that folder.

For example, express.static('/var/www') would serve the files in that folder. So a request to your Node server for http://server/file.html would serve /var/www/file.html.

routerはルートを実行するコードです。 を実行すると、実際にコールバック関数を呼び出してリクエストを処理するのはapp.get('/user', function(req, res) { ... });です。router

渡す順序app.useによって、各ミドルウェアがリクエストを処理する機会が与えられる順序が決まります。たとえば、test.htmlstatic フォルダーに次のようなファイルがあり、ルートがある場合:

app.get('/test.html', function(req, res) {
    res.send('Hello from route handler');
});

どれがリクエスト元のクライアントに送信されますかhttp://server/test.html? どちらのミドルウェアがuse最初に渡されるかです。

こうすると:

app.use(express.static(__dirname + '/public'));
app.use(app.router);

その後、ディスク上のファイルが提供されます。

逆にやると、

app.use(app.router);
app.use(express.static(__dirname + '/public'));

次に、ルート ハンドラーがリクエストを取得し、「Hello from route handler」がブラウザーに送信されます。

通常、ルーターを静的ミドルウェアの上に配置して、誤って名前を付けたファイルがルートの 1 つを上書きできないようにします。

を明示的に指定しない場合は、ルートを定義する時点で Express によって暗黙的に が追加されることに注意してくださいuse(routerをコメント アウトしてもルートが機能するのはこのためですapp.use(app.router))。


コメント投稿者は育てられたstaticとの順序に関してrouter私が触れていなかったもう 1 つのポイントは、アプリの全体的なパフォーマンスへの影響です。

use router上記のもう一つの理由は、staticパフォーマンスを最適化するためです。static先頭にすると、ファイルが存在するかどうかを確認するために、すべてのリクエストでハードドライブにアクセスします。クイックテスト負荷がかかっていないサーバーでは、このオーバーヘッドは約 1 ミリ秒になることがわかりました (負荷がかかっていて、ディスク アクセスの要求が競合する場合は、この数値がさらに高くなる可能性があります)。

first を使用するとrouter、ルートに一致するリクエストがディスクにアクセスする必要がなくなり、貴重な数ミリ秒を節約できます。

もちろん、staticのオーバーヘッドを軽減する方法はあります。

最善の選択肢は、すべての静的リソースを特定のフォルダーの下に置くことです。(IE /static) 次に、staticそのパスにマウントして、パスが で始まる場合にのみ実行されるようにすることができます/static

app.use('/static', express.static(__dirname + '/static'));

このような状況では、これを上に置きますrouter。これにより、ファイルが存在する場合に他のミドルウェア/ルーターの処理を回避できますが、正直なところ、それほど多くのメリットがあるとは思えません。

また、staticCacheは、静的リソースをメモリ内にキャッシュするため、よく要求されるファイルのためにディスクにアクセスする必要がありません。(警告: staticCache 削除されるようです将来。)

ただし、否定的な回答(ファイルが存在しない場合)はキャッシュされないと思うので、パスにマウントせずに上記をstaticCache実行しても役に立ちません。staticCacherouter

パフォーマンスに関するすべての質問と同様に、実際のアプリを(負荷をかけた状態で)測定およびベンチマークして、実際にボトルネックがどこにあるかを確認します。


エクスプレス4

Express 4.0では が削除されます app.router。すべてのミドルウェア ( app.use) とルート (app.getなど) は、追加された順序どおりに処理されるようになりました。

言い換えると:

すべてのルーティング メソッドは、表示される順序で追加されます。 は実行しないapp.use(app.router)でください。これにより、Express で最も一般的な問題が解消されます。

つまり、 と を混ぜるapp.use()と、呼び出された順序どおりapp[VERB]()に動作します。

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

Express 4 の変更点について詳しくはこちらをご覧ください。

おすすめ記事