用Express嵌套路由器的正确/简洁方法

9
我可以这样设置两个路由: index.js
var express = require('express');
var app = express();
var router = express.Router();
const PORT = 3001;

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

app.use('/routes', require('./routes'));

app.listen(PORT, function(){
    console.log('listening on port:', PORT);
});

./routes/index.js

var express = require('express');
var app = express();
var router = express.Router();

router.use('/sub1', require('./sub1'));
router.use('/sub2', require('./sub2'));

module.exports = router;

./routes/sub1.js

var express = require('express');
var app = express();
var subOneRouter = express.Router();

subOneRouter.get('/', function(req, res){
    res.json({route: 'sub1-base'});
});

subOneRouter.get('/:id', function(req, res){
    res.json({'route': 'sub1-base', 'id': req.params.id});
});

module.exports = subOneRouter;

为了简洁起见,./routes/sub2.js看起来和sub1.js一样,但它的变量名为subTwo。
如何最短地将sub2嵌套在sub1中?在index.js中,我尝试过…
var subOne = router.use('/sub1', require('./sub1'));
subOne.use('/sub2', require('./sub2'));

但那根本没有起作用。在 index.js 中。
router.use('/sub1/:id/sub2', require('./sub2'));
//localhost:3000/sub1/123/sub2/456 => { "route": "sub2-base","id":"456"}

虽然这种方式可以工作,但如果结构变得更长,代码可能会变得冗长且难以维护。有没有更短的嵌套方式来实现同样的效果呢?


你的 URL 应该是 localhost:3000/routes/... ,在你的 sub1.js 文件中,你应该像这样定义一个路由: subOneRouter.get('/:id/sub2', require('./sub2.js'); ,URL 应该是 localhost:3000/routes/sub1/123/sub2。 - Molda
3个回答

6
你在 index.js 中的代码让人难以理解你想要什么。根据我目前的理解,你想要一个类似于 /sub1/:id/sub2 的路由,但更易于编写和维护,并且在 index.js 中实现。
是的,你可以这样做,而且很简单。你只需要 require sub1sub2 并在 sub1 中使用 sub2,然后你就可以将 sub1 挂载到路由器上。
例如:
var sub1= require('./sub1');
var sub2 = require('./sub2');
sub1.use(sub2);
router.use('/sub1:id', sub1);

那么你的index.js应该是这样的:

var express = require('express');
var app = express();
var router = express.Router();
const PORT = 3001;

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

var sub1= require('./sub1');
var sub2 = require('./sub2');
sub1.use(sub2);

router.use('/sub1:id', sub1);

app.listen(PORT, function(){
    console.log('listening on port:', PORT);
});

这个并不难维护。如果这不是你想要的,请告诉我。


2

So you have

/routes/sub1  
/routes/sub1/:id  
/routes/sub2  
/routes/sub2/:id 

如果我理解正确,您想要这些路由:

/routes/sub1/sub2
/routes/sub1/sub2/:id
/routes/sub1/:id/sub2
/routes/sub1/:id/sub2/:id

所以你的解决方案可以类似于这样:
var express = require('express'),
    app = express();
    routerA = express.Router(),  
    routerB = require('./sub2');

routerA.get('/', function(req, res) { console.log('sub1 base') });

//The next 2 mounts order matters, cause they can overlap each other
routerA.use('/sub2', routerB); //routes/sub1/sub2 + routes/sub1/sub2/:id
routerA.get('/:id', function(req, res) { console.log('sub1 id:' + req.params.id) });

routerA.use('/:id/sub2', routerB); //routes/sub1/:id/sub2 + routes/sub1/:id/sub2/:id

app.use('/routes', routerA);
app.listen(3000);

由您决定是否会有一个名为'sub2'的子ID。
因为任何对于ID为'sub2'的资源的请求都将被路由器B接管。


-1
我建议编写node.js路由的方式是创建一个routes.js文件,其中包含所有路由。
然后,您可以在routes.js文件中添加sub1的路由,如下所示:
const router = require('express').Router();

const sub1 = require('./sub1');
router.use('/sub1', sub1);

module.exports = router;

然后我会在 sub1.js 中放置你的 sub2 路由,就像这样:

const subOneRouter = require('express').Router();

subOneRouter.get('/', function(req, res){
    res.json({route: 'sub1-base'});
});

subOneRouter.get('/:id', function(req, res){
    res.json({'route': 'sub1-base', 'id': req.params.id});
});

const sub2 = require('./sub2');
subOneRouter.use('/:id/sub2);

module.exports = subOneRouter;

这将使您所有的sub1路由都具有'/sub1'前缀,而所有在sub1内部的sub2前缀都具有'/:id/sub2'前缀。然后,您可以随意放置任何您希望在sub2中的路由。

使用此设置意味着如果您想要更改sub1或sub2的前缀,您只需在一个地方更改即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接