0

我开始使用 node.js 并表达一些宁静的 API。我将我的逻辑分解为控制器。每个控制器都有一些与我的 API 正在执行的操作相对应的方法。我不想每次向现有控制器添加新功能或使用新控制器添加全新功能时都必须更新路由。为此,我试图让我的 restful api 由一组简单的路由定义,并且足够聪明,可以根据现有的控制器和方法来解决问题。为此,我有这个...

"use strict";

module.exports = function (app) {
    var routes = [
        {
            'get'        : true,
            'put'        : false,
            'post'       : false,
            'update'     : false,
            'delete'     : false,
            'controller' : '',
            'action'     : 'search',
            'url'        : '/:controller/search/:query/:page?'
        },
        {
            'get'        : true,
            'put'        : false,
            'post'       : false,
            'update'     : false,
            'delete'     : false,
            'controller' : '',
            'action'     : '',
            'url'        : '/:controller/'
        },
        {
            'get'        : true,
            'put'        : false,
            'post'       : true,
            'update'     : true,
            'delete'     : true,
            'controller' : '',
            'action'     : '',
            'url'        : '/:controller/:id'
        },
        {
            'get'        : true,
            'put'        : false,
            'post'       : true,
            'update'     : false,
            'delete'     : false,
            'controller' : '',
            'action'     : '',
            'url'        : '/:controller/:id/:action'
        }
    ];

    function setupRoute(method, item) {
        if (method in item && item[method]) {
            console.log('Init route: ' + method.toUpperCase() + ' ' + item.url);
            app[method](item.url, function(req, res) {
                var c = '';
                if ('controller' in item) {
                    c = item.controller;
                }
                var a = '';
                if ('action' in item) {
                    c = item.action;
                }

                if ('controller' in req.params) {
                    c = req.params.controller;
                }
                if ('action' in req.params) {
                    a = req.params.action;
                }
                if (c == '') {
                    c = 'default';
                }
                if (a != '') {
                    a += '_';
                }
                a += req.method.toLowerCase();

                c = c.toLowerCase();
                a = a.toLowerCase();

                if (c in app.controllers) {
                    if (a in app.controllers[c]) {
                        app.controllers[c][a](req, res);
                    } else {
                        console.log('Unknown action on controller ' + a);
                        res.status(400).send('Bad Request');
                    }
                } else {
                    console.log('Unknown Controller  ' + c);
                    res.status(404).send('Not found');
                }
            });
        } else {
            app[method](item.url, function(req, res) {
                res.status(405).send('Method Not Allowed');
            }
        }
    }

    routes.forEach(function(item) {     
        setupRoute('get', item);
        setupRoute('put', item);
        setupRoute('post', item);
        setupRoute('update', item);
        setupRoute('delete', item);
    });
}

以这种方式设置有什么问题吗?

有没有更好的方法来做到这一点?

4

2 回答 2

2

我已经尝试了许多不同的方法来分解 node.js 中的路由。如果你在做一个小应用程序,把它们放在 app.js 中是有意义的,但如果你开始有很多不同的路由由很多不同的控制器处理,它很快就会变得混乱。如果您尝试做的工作(并且我建议进行广泛的测试),那么我认为这样做很好,但请记住,复杂的“魔术”可能会慢,难以维护,并且难以调试。有一段时间,我试图做类似的事情,但最终选择通过向每个控制器添加“register_routes”方法来简化。所以是这样的:

module.exports = {
    register_routes: function(app, callback) {
        app.get('/something', function(req, res){
            // Do stuff
        });
        callback();
    }
}

然后在 routes/index.js

module.exports = [
    require('./something'),
    require('./something_else') // etc...
];

然后在 app.js

var controllers = require('routes');
async.eachSeries(controllers, function(controller, cb){
    controller.register_routes(app, cb);
}, function(err){
    // done
});

请注意,建议在 register_routes 中使用回调,以便以正确的顺序注册路由。

可能有一些方法可以在 express 中构建路线,但一般来说,如果它有效,它应该没问题(特别是如果它是你的项目)。

但是,就像 danielepolencic 建议的那样,您可能喜欢其他更自然地处理路由的框架。

于 2013-08-24T14:14:40.567 回答
0

在我看来,您更喜欢拥有一个包含所有路由的配置文件,而不是按照通常的方式快速构建应用程序。如果是这种情况,我建议切换到Hapi。Hapi 是一个以配置为中心的框架,可让您轻松地从配置对象构建 API。这听起来正是你想要做的。

于 2013-08-24T09:50:40.837 回答