express.Router和app.get之间的区别?


265

我从NodeJS和Express 4开始,我有些困惑。我正在阅读Express网站,但是看不到何时使用路由处理程序或何时使用express.Router

如我所见,例如,如果我想在用户点击时显示页面或其他内容,/show则应使用:

var express = require('express')    
var app = express()    
app.get("/show", someFunction)  

一开始,我认为这很旧(对于Express 3)。是这样吗,还是Express 4也是如此?

如果这是在Express 4中实现的方式,那么它的express.Router用途是什么?

我读了几乎与上面相同的示例,但是使用了express.Router

var express = require('express');
var router = express.Router();
router.get("/show", someFunction)

那么,两个示例之间有什么区别?

如果我只想创建一个简单的测试网站,应该使用哪一个?


27
A Router本身并不.listen()要求。这是非常有用的应用程序分成多个模块-创建一个Router每个了app可以require().use()中间件。
乔纳森·洛诺夫斯基

5
正如@JonathanLonowski所暗示的那样,app.get(..)语法只是使使用起来express.router更加方便的捷径。如果您只是刚入门,请不要担心路由器的细节。
soulprovidr

1
所以您是说我暂时只应使用app.get()?仍然对何时使用另一个感到困惑
nelson687

11
@ nelson687他们之间确实没有硬性规定。如果您觉得app's自己的路由方法(例如)app.get()足以满足需要,请使用它们。的Router是就在那里为方便起见,以帮助您组织了多模块应用。从引导:“ express.Router类可用于创建模块化安装路由执行甲。Router实例是一个完整的中间件和路由系统;为此原因,它通常被称为一个‘小应用程序’。
乔纳森Lonowski

Answers:


323

app.js

var express = require('express'),
    dogs    = require('./routes/dogs'),
    cats    = require('./routes/cats'),
    birds   = require('./routes/birds');

var app = express();

app.use('/dogs',  dogs);
app.use('/cats',  cats);
app.use('/birds', birds);

app.listen(3000);

dogs.js

var express = require('express');

var router = express.Router();

router.get('/', function(req, res) {
    res.send('GET handler for /dogs route.');
});

router.post('/', function(req, res) {
    res.send('POST handler for /dogs route.');
});

module.exports = router;

var app = express()被调用时,会返回一个应用对象。将此视为主要应用程序

var router = express.Router()被调用时,一个稍微不同的迷你应用程序返回。微型应用程序背后的想法是,应用程序中的每条路线都可能变得非常复杂,并且将所有代码移入一个单独的文件中将使您受益。每个文件的路由器都变成一个微型应用程序,其结构与主应用程序非常相似。

在上面的示例中,/ dogs路由的代码已移至其自己的文件中,因此不会干扰主应用程序/ cats/ birds的代码在它们自己的文件中的结构类似。通过将此代码分成三个微型应用程序,您可以独立地处理每个应用程序的逻辑,而不必担心它将如何影响其他两个应用程序。

如果您具有与所有这三个路由有关的代码(中间件),则可以在调用之前将其放在主应用程序中app.use(...)。如果您的代码(中间件)仅与那些路由之一有关,则可以将其仅放入该路由的文件中。


您是否应该传递该应用程序对象,app.use('/dogs', dogs)(app)因为您正在那里定义路由,另外(如果我做错了,请更正我),如果这样做的话,该应用程序对象之前已放置了所有中间件并且其他中间件将被添加到应用程序对象(假设更多的中间件位于“狗狗路线”中)。如果您使用route.get('/dogs', route)它,则仅在与该路由器中定义的路由进行交互时将中间件传递给应用程序对象,并且如果应用程序的范围不在路由范围内,则它无权访问该中间件。
乌鸦2015年

1
您无需将应用传递到路由,因为路由是通过传递给应用的app.use('/dogs', show)。这样,路由就独立于应用程序,并且可以在任何Express应用程序中重复使用。中间件放置在该路由使用的路由之前的任何位置。如果将中间件放在app.js中的所有路由之上,那么所有路由都将使用该中间件。如果将中间件放置在路由文件(dogs.js)中,则只有该路由会使用它。如果将中间件放置在dogs.js中的GET路由之后,则只有POST路由会使用它(只要它以响应结尾)。
2015年

啊,我的坏。我的意思是说,app.get('/dogs'dogs,)(app)因为问题是关于app.get和route.get的获取功能。您正在展示如何分隔路线以使其易于管理。但是,如果我们在谈论我的轶事是不正确的app.get?如果可以在PC上使用,请修改上面的注释。
2015年

2
当我使用express.Router()或express()时,我的应用程序仍然可以工作,我无法理解不同之处:(
Ajay Suwalka

3
@Ajay Suwalka我不知道该如何对已经说过的内容进行详细说明。文档说“路由器对象是中间件和路由的隔离实例”。我也喜欢@Jonathan Lonowski在上面的评论,“ A Router不能单独.listen()请求”。那可能是主要区别。
Nocturno

29

Express 4.0随附了新的路由器。如网站上所述:

express.Router类可用于创建模块化可安装的路由处理程序。路由器实例是完整的中间件和路由系统;因此,它通常被称为“迷你应用程序”。

https://scotch.io/tutorials/learn-to-use-the-new-router-in-expressjs-4中有一篇很好的文章,描述了差异以及如何使用路由器。

总结一下

使用路由器,您可以更轻松地将代码模块化。您可以将路由器用作:

  1. 基本路线:首页,关于
  2. 路由中间件以将请求记录到控制台
  3. 带参数的路线
  4. 路由中间件获取参数以验证特定参数
  5. 验证传递给特定路由的参数

注意:

app.router在Express 4中删除的对象在Express 5中又卷土重来。在新版本中,它只是对基本Express路由器的引用,与Express 3不同,在Express 3中,应用程序必须显式加载它。


7
app.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Post a random book')
  })

如上例所示,我们可以在路由下添加不同的HTTP请求方法。


5

假设您的应用程序有点复杂。因此,我们首先要做的是将应用程序划分为多个模块,以便一个模块中的更改不会使其他模块杂乱无章,您可以继续处理单个模块,但是最终,您需要将所有内容集成到一个模块中正在构建一个应用程序。就像我们有一个主应用程序,而有几个父级应用程序是子应用程序一样。因此,当我们创建父应用程序时,我们使用

var express = require('express');
var parent = express();

而对于这个父应用程序,我们需要引入子应用程序。但是,由于子应用程序不是完全不同的应用程序(因为它们在相同的context-java术语中运行),因此express通过Expresse的Router函数提供了实现此功能的方法,这是我们在每个子模块文件中所做的工作,让我们将其中一个子模块称为aboutme

var express = require('express');
var router = express.Router();
/**
** do something here
**/
module.exports = router;

通过module.exports,我们使该模块可供其他用户使用,并且由于我们已经进行了模块化,因此需要像其他任何第三方模块一样,通过节点的require函数使模块文件对父应用程序可用,并且父文件看起来这样的事情。

var express = require('express') 
var parent = express() 
var child = require(./aboutme)

在使该子模块对父级可用之后,我们需要告诉父级应用程序何时使用该子级应用程序。可以说,当用户点击关于我的路径时,我们需要关于我的子应用程序来处理该请求,我们使用Expresse的use方法来完成该请求。

parent.use('/aboutme',  aboutme);

一口气,父文件看起来像这样

var express = require('express');
var parent = express();
var child = require(./aboutme);
/***
**do some stuff here
**/
parent.use('/aboutme',child);

最重要的是,父母可以做的是启动一个服务器,而孩子不能这样做。希望这可以澄清。有关更多信息,您可以随时查看源代码,这需要花费一些时间,但它可以为您提供很多信息。谢谢。


1
这不是parent.use('/aboutme', child)吗?
Kees de Kooter,

2

使用app.js编写路由意味着在应用程序启动时加载app.js的所有用户都可以访问它们。但是,将路由放入express.router()微型应用程序会保护并限制其可访问性。


2

express.Router 有很多选择:

  • 启用区分大小写:/show路由与不相同/Show,默认情况下禁用此行为
  • 严格路由模式:/show/路由到与相同/show,默认情况下也禁用此行为
  • 我们可以将特定的中间件添加到特定的路由

0

总之,与中间件express.Router相比,它可以做更多的事情app.get(),此外,您可以使用express.Router()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.