使用一条switch语句合并许多路由

时间:2019-07-09 16:02:13

标签: javascript express express-router

我正在创建一个供生产使用的应用程序,并希望使用一个switch语句合并多个路由。我目前在开发中使用它,并且效果很好,但是我之前从未见过这种方法,并且想知道是否有原因。 使用这种方法有什么问题吗?如果是这样,请真正在答案中寻找为什么

这是我要做的,而不是创建多条路线。

router.post('/save', auth, async (req, res)=>{
    switch(req.body.action) {
        case 'user':
            result = await asyncSaveUser(req.body.data);
            break;
        case 'order':
            result = await asyncSaveOrder(req.body.data);
            break;
        default:
            result = {success:false, data: 'not valid action'};
            break;     
    }
    return res.status(200).json(result);
})

在API中,我将创建一个动作。

url: {baseUrl}+'/save'
body: {
    "action":"user",
    "data": {"fn": John, "ln": Doe}
}

1 个答案:

答案 0 :(得分:0)

两个问题:

  • 一个功能会随着时间的流逝而变得相当大。提醒您,您已经将逻辑分离为单独的功能(我稍后会再讨论)。
  • 保存用户和保存订单在根本上是不同的操作,但是,如果URL的任一方向为/save,则日志记录,报告等将变得更加困难。差异(用户与订单)隐藏在POST数据中,而不是URL中。

如果您全部执行一项功能,route parameters就可以解决日志记录等问题。例如:

router.post('/users/:action', async function (req, res) { // Added `async`, since you're using `await`
    switch(req.params.action) {
        case 'user':
            result = await asyncSaveUser(req.body.data);
            break;
        case 'order':
            result = await asyncSaveOrder(req.body.data);
            break;
        default:
            result = {success:false, data: 'not valid action'};
            break;     
    }
    return res.status(200).json(result);
})

回避避免让此函数过长:您可以使用调度对象:

const actionDispatch = {
    action: async asyncSaveUser(data) {
        // ...
    },
    user: async asyncSaveUser(data) {
        // ...
    }
};
function invalidAction() {
    return {success:false, data: 'not valid action'};
}

router.post('/users/:action', async function (req, res) {
    const actionFunction = actionDispatch[req.params.action] || invalidAction;
    const result = await actionFunction(req.body.data);
    return res.status(200).json(result);
});

当然,actionDispatch对象可能开始变得冗长。您可能会对其进行更多细分,这是维护的缺点(在其他地方定义它们时必须列出其中的功能)。


旁注:当心将async函数传递给不了解其返回内容的某些东西(router.post)(一个承诺)。如果这样做,则几乎必须将整个主体包装在try / catch中以处理错误(除非这些处理程序有一些中间件处理承诺)。