【问题标题】:Express call GET method within route from another route [duplicate]从另一条路线的路线内快速调用GET方法[重复]
【发布时间】:2016-12-27 02:24:45
【问题描述】:

我有多个路线。如何通过在组路由的 GET 方法中调用用户路由(GET 方法)来获取数据?这样做的最佳方法是什么?

我的 app.js 看起来像这样:

var express = require('express');

var routes = require('./routes/index');
var users = require('./routes/users');
var groups = require('./routes/groups');

var app = express();

app.use('/', routes);
app.use('/users', users);
app.use('/groups', groups);

module.exports = app;
app.listen(3000);

然后我还有另一个文件 routes/users.js:

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

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('GET ON THE users!');
});

module.exports = router;

还有一条路由routes/groups.js:

var express = require('express');
var router = express.Router();
var otherRouter = require('./users')

/* GET groups listing. */
router.get('/', function(req, res, next) {

    // call the get on users and retrieve all data from that request

    res.send('GET for the groups');
});

module.exports = router;

【问题讨论】:

  • 只需要计算出/users 路由的数据响应是什么的代码,并将其放在一个单独的函数中。然后从您要使用它的两个地方调用该函数。如果它是异步的,那么让函数返回一个用数据解析的承诺。然后,您可以在需要它的两个地方使用该异步接口。
  • 您应该将其作为实际答案发布。我想我可以以某种方式调用现有的路由获取方法。谢谢您的回答! :)
  • 我正在研究同样问题的答案,因为“你不应该那样做”的答案对我来说不够好:) 直接调用应用程序(类似于“runMiddleware” ' 答案/示例做到了,除了来自npmjs.com/package/node-mocks-http 的模拟)我觉得会产生一个很好的'内部运行'能力。也就是说,app(mock_req, mock_res) 然后检查响应。

标签: node.js express run-middleware


【解决方案1】:

我已经为这个uest做了一个专用的中间件,在这里查看我的详细答案:https://stackoverflow.com/a/59514893/133327

【讨论】:

    【解决方案2】:

    对于从谷歌来到这里的人。如果您需要点击一条或多条路线并跳过 http 请求,您也可以使用supertest

    const request = require("supertest");
    
    app.get("/usersAndGroups", async function(req, res) {
        const client = request(req.app);
        const users = await client.get("/users");
        const groups = await client.get("/groups");
    
        res.json({
            users: users.body,
            groups: groups.body
        });
    });
    

    您也可以与Promise.all同时运行它们

    【讨论】:

    • 我只在测试中使用过supertest——在prod中可以这样使用吗?
    【解决方案3】:

    我考虑了“转发”的解释,它非常有用,并且可以在其他框架和其他语言中使用。

    此外,作为“转发”,它不会从后续 HTTP 响应中产生任何开销。

    对于 Express,4.X 版本提供以下内容。可能还有其他版本,但我没有检查。

    var app = express()
    
    function myRoute(req, res, next) {
      return res.send('ok')
    }
    
    function home(req, res, next) {
       req.url = '/some/other/path'
    
       // below is the code to handle the "forward".
       // if we want to change the method: req.method = 'POST'        
       return app._router.handle(req, res, next)
    }
    
    app.get('/some/other/path', myRoute)
    app.get('/', home)
    

    【讨论】:

    • 我相信这最好地回答了这个问题,无论它是否更优化。
    • 我收到TypeError: Cannot read property 'handle' of undefined
    • @golimar ,假设您使用的是 4.X ,我们需要查看您的代码才能确定(可以在新问题中发布)。但是从您的消息来看,._router 似乎未定义,因此您可能没有像我的示例中那样通过“app”变量定义 express,因此需要将“app”更新为您使用的任何变量'正在使用的是。 IE "VARIABLE_YOUR_USING_FOR_EXPRESS._router.handle
    【解决方案4】:

    您不应该为此使用路由。只需调用负责从 GET 组路由中检索用户的函数并使用该数据执行您需要的操作。您提议的方式要贵得多,因为您必须进行 http 调用。

    为简单起见,我假设您的逻辑是同步的,并且数据存储在 data/users.js 中:

    var data = [{id:1, name: "one"},{id: 2, name: "two"}];
    module.exports = function(){
      return data;
    };
    

    在路由/users.js 中:

    var express = require('express');
    var router = express.Router();
    var getUsers = required('./../data/users');
    
    router.get('/', function(req, res, next) {
      res.send(getUsers());
    });
    

    在路由/groups.js 中:

    var express = require('express');
    var router = express.Router();
    var otherRouter = require('./users')
    var getUsers = require('./.../data/users');
    
    router.get('/', function(req, res, next) {
      var users = getUsers();
      //do some logic to get groups based on users variable value
      res.send('GET for the groups');
    });
    

    【讨论】:

    • 那行得通。谢谢! :D 我认为我实际上可以直接调用用户路由器的 get 方法。我不想打开一罐温暖的东西,但是在做需要从其他路由中调用路由方法的中间件时,这是最佳实践吗?再次感谢您的及时回复。
    • 很高兴能帮上忙。如果此建议解决了问题,请将问题标记为已回答。
    • 这并不是对名义问题的真正答案。
    【解决方案5】:

    你可以使用 run-middleware 模块来做这个

    app.runMiddleware('/pathForRoute',{method:'post'},function(responseCode,body,headers){
         // Your code here
    })
    

    更多信息:

    披露:我是这个模块的维护者和第一个开发者。

    【讨论】:

      猜你喜欢
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 2012-12-05
      • 2018-09-05
      相关资源
      最近更新 更多