我想遵循DRY原则并简化此快速服务器上的路由?

时间:2016-08-07 17:40:44

标签: node.js express routing

我设置了以下快速服务器(服务器只是来自另一个文件的express())。我确信有一种方法可以将其简化为只有一个server.get()但我无法弄清楚如何。任何帮助或正确方向的点将不胜感激。

module.exports.api = function (server, fs) {

    server.get('/api/getData/:uuid', function (req, res) {
        fs.readFile(__dirname + '/data.json', function (err, data) {
            if (err) throw err;
            data = JSON.parse(data);
            data.forEach(function (match) {
                match['uuid'] = match['x'] + '-' + match['y'];
            });
            var match = data.filter(function (e) {
                return e.uuid == req.params.uuid
            })[0];
            res.send(200, match);
        });
    });

    server.get('/api/getData', function (req, res) {
        fs.readFile(__dirname + '/data.json', function (err, data) {
            if (err) throw err;
            data = JSON.parse(data);
            data.forEach(function (match) {
                match['uuid'] = match['x'] + '-' + match['y'];
            });
            res.send(200, data);
        });
    });
};

1 个答案:

答案 0 :(得分:1)

这是一个解决方案,它只是将公共代码移动到共享功能中,但仍然使用这两条路由来明确路由:

function getData(res, uuid) {
    fs.readFile(path.join(__dirname, 'data.json'), function (err, fileData) {
        if (err) {
            return res.send(500);
        }
        let data = JSON.parse(fileData);
        data.forEach(function(match) {
            match['uuid'] = match['x'] + '-' + match['y'];
        });
        if (uuid) {
            var match = data.filter(function (e) {
                return e.uuid == uuid;
            })[0];
        }
        res.send(200, match);
    });
}


module.exports.api = function (server, fs) {
    server.get('/api/getData/:uuid', function (req, res) {
        getData(res, req.params.uuid);
    });

    server.get('/api/getData', function (req, res) {
        getData(res);
    });
};

这改变了以下内容:

  1. 将共享代码放入从两个路由调用的getData()函数中。
  2. 如果fs.readFile()出错,则发送错误回复
  3. 创建新的局部变量,因此它不会分配回函数参数,而现在这是一种不太理想的做法,因为它会阻止一些解释器优化。
  4. 使用path.join()以更跨平台的方式加入路径的某些部分。
  5. 仅供参考,除非data.json中的数据实际上经常发生变化,否则您只需将此数据读入变量一次,然后对其进行缓存,而不是将其重新读取到每个请求中。

    注意:您可以使用路由通配符并将代码减少到单个路由,但这通常被认为是反模式,因为通配符通常比您想要的更多,创建了您手动触发404错误的情况不打算匹配最终匹配您的路由通配符。因此,明确声明您想要匹配的路由并且只是共享适当的实现代码而不是尝试将事物折叠到匹配多种形式的URL的单个路由被认为是一件好事。

    当然,总有一些例外情况要记住,目标是清晰,正确,可维护,可靠的代码,不一定是最少的路线。

    如果您只想在服务器启动时缓存data.json数据,可以使用require()为您加载和解析它,然后才真正没有理由进行sharef功能:

    const cacheData = require('./data.json');
    cacheData.forEach(function(match) {
        match['uuid'] = match['x'] + '-' + match['y'];
    });
    
    module.exports.api = function (server, fs) {
        server.get('/api/getData/:uuid', function (req, res) {
            let match = cacheData.filter(function (e) {
                return e.uuid == req.params.uid;
            })[0];
            res.send(match);
        });
    
        server.get('/api/getData', function (req, res) {
            res.send(cacheData);
        });
    };