使用一个 switch 语句组合多个路由
Combining many routes using one switch statement
我正在创建一个供生产使用的应用程序,并希望使用一个 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}
}
两个问题:
- 随着时间的推移,这个函数往往会变得相当大。请注意,您已经将逻辑隔离到单独的函数中(稍后我会回过头来)。
- 保存用户和保存订单是根本不同的操作,但是如果 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
) returns(承诺)。如果这样做,您几乎必须将整个主体包装在 try
/catch
中以处理错误(除非这些处理程序有一些中间件处理承诺)。
我正在创建一个供生产使用的应用程序,并希望使用一个 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}
}
两个问题:
- 随着时间的推移,这个函数往往会变得相当大。请注意,您已经将逻辑隔离到单独的函数中(稍后我会回过头来)。
- 保存用户和保存订单是根本不同的操作,但是如果 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
) returns(承诺)。如果这样做,您几乎必须将整个主体包装在 try
/catch
中以处理错误(除非这些处理程序有一些中间件处理承诺)。