在REST API中组合2个查询的输出

时间:2016-08-08 16:21:52

标签: node.js rest restify

我正在使用node.js restify模块。我有一个REST API,它在json中输出单个MySQL查询的结果。以下是API的代码;

var rest_api_get_list = function (app, url_name) {
    function respond(req, res, next) {
        var door_mac = req.query.door_mac;

        var connection = own_mysql.getMySQL_connection();

        var query_str =
                "SELECT doors.mac_addr, " +
                "sensors.sensor_type " +
                "FROM sensors " +
                "WHERE (doors.mac_addr = ?) "
            ;

        var query_var = [door_mac];

        var query = connection.query(query_str, query_var, function (err, rows, fields) {
            //if (err) throw err;
            if (err) {
                //throw err;
                console.log(err);
                logger.info(err);
            }
            else {
                res.send(rows);
            }
        }); 
        return next();
    }

    app.get(url_name, respond);
};

假设我有另一个看起来像这样的查询;

    var query_str_2 =
            "SELECT knobs.mac_addr, " +
            "furniture.furniture_type " +
            "FROM furnitures" +
            "WHERE (knobs.mac_addr = ?) "
        ;

我想结合2个MySQL查询query_strquery_str_2的输出,并让REST API在json中返回结果。如何才能做到这一点?

为了更清楚,我正在考虑代码做这样的事情;

var rest_api_get_list = function (app, url_name) {
    function respond(req, res, next) {
        var door_mac = req.query.door_mac;

        var connection = own_mysql.getMySQL_connection();

        var query_str =
                "SELECT doors.mac_addr, " +
                "sensors.sensor_type " +
                "FROM sensors " +
                "WHERE (doors.mac_addr = ?) "
            ;

        var query_var = [door_mac];

        var query = connection.query(query_str, query_var, function (err, rows_output_1, fields) {
            //if (err) throw err;
        }); 

        var query_str_2 =
            "SELECT knobs.mac_addr, " +
            "furniture.furniture_type " +
            "FROM furnitures" +
            "WHERE (knobs.mac_addr = ?) "
        ;

        var query_2 = connection.query(query_str_2, query_var, function (err, rows_output_2, fields) {
            //if (err) throw err;

        }); 

        //How to display json output of rows_output_1 and rows_output_2?

        return next();
    }

    app.get(url_name, respond);
};
编辑:我开始赏金以吸引使用Promises的答案。

2 个答案:

答案 0 :(得分:6)

用于管理异步控制流的模块(如async)可以帮助您解决此问题。

例如:

function respond(req, res, next) {

    var door_mac = req.query.door_mac;
    var connection = own_mysql.getMySQL_connection();
    var query_var = [door_mac];

    async.parallel([
        function (callback) {

            var query_str =
                "SELECT doors.mac_addr, " +
                "sensors.sensor_type " +
                "FROM sensors " +
                "WHERE (doors.mac_addr = ?) "
            ;
            connection.query(query_str, query_var, callback); 
        },
        function (callback) {

            var query_str_2 =
                "SELECT knobs.mac_addr, " +
                "furniture.furniture_type " +
                "FROM furnitures" +
                "WHERE (knobs.mac_addr = ?) "
            ;
            connection.query(query_str_2, query_var, callback);
        }
    ], function (error, results) {

        // results[0] => result for query_str
        // results[1] => result for query_str_2
        // ... return next() or whatever
    })       
}

答案 1 :(得分:3)

如果你要求并行性,正如@cartant所说,你可以使用 async 或(更好)承诺(Promise.all(p1, p2).then(...))。

但是,如果您要求采用最佳方法(并行性会以每次实际结果消耗的更多资源为代价提供更快的结果),您可以在单个查询中执行此操作:

var query_str =
    "SELECT doors.mac_addr, " +
    "sensors.sensor_type as type " +
    "FROM sensors " +
    "WHERE (doors.mac_addr = ?) " +
    "UNION " +
    "SELECT knobs.mac_addr, " +
    "furniture.furniture_type as type " +
    "FROM furnitures" +
    "WHERE (knobs.mac_addr = ?) "
;

这样,您可以执行单个数据库调用,当然,数据库不会执行任何并行操作,相反,它会尽最大努力在资源消耗较低的情况下在最佳时间获得答案。

所以,如果你要参加更多的请求,平均效率会更好,另一方面,如果你在资源不太关心的环境中要求更快的结果,那么并行方法将会更好。