我的 API 有三个端点:articles、websites和users。每个article都与一个website. Auser也可以分享articles。
在我的 API 中,我刚刚在/website/:id/articles. 这将查询articles与给定关联的数据库website。然后,它根据谁在与 API 交谈(例如,“用户是否分享了这篇文章?”)对每篇文章的数据执行一些操作。
我现在继续在/users/:id/shared-articles. 对此的数据库查询略有不同,但我想对查询后的文章数据执行的操作与以前相同。
这是前一个端点的一些伪代码:
router.get('/websites/:id/articles', function (req, res) {
articleService.find({ websiteId: req.params.id }, function (error, foundArticles) {
async.waterfall([
function (cb) {
// Manipulate foundArticles…
cb(null, manipulatedArticles)
},
function (articles, cb) {
// Manipulate articles some more…
cb(null, manipulatedArticles)
},
], function (error, articles) {
if (error) {
return res.json(error, 400)
}
res.json(articles)
})
})
})
为了创建我的新端点,/users/:id/shared-articles我可以将操作任务抽象为一个可以由我的两个端点共享的函数(如上图所示),从而减少代码重复。
router.get('/websites/:id/articles', function (req, res) {
articleService.find({ websiteId: req.params.id }, function (error, foundArticles) {
manipulateArticles(foundArticles, function (articles) {
if (error) {
return res.json(error, 400)
}
res.json(articles)
})
})
})
router.get('/users/:id/shared-articles', function (req, res) {
shareActionService.find({ userId: req.params.id }, function (error, foundShareActions) {
var sharedArticleIds = { _id: { $in: _.pluck(foundShareActions, 'sharedArticleId') } }
articleService.find(sharedArticleIds, function (error, foundArticles) {
manipulateArticles(foundArticles, function (articles) {
if (error) {
return res.json(error, 400)
}
res.json(articles)
})
})
})
})
但是,我认为在 Node 中设计 API 时,这种代码重用问题一定很常见,我想知道这里是否有明显更好的解决方案。
我的一个想法是让所有文章子资源(例如/users/:id/shared-articles或/websites/:id/links)在/links内部与 API 对话,它本身将处理我上面提到的操作。那么问题是我必须/links在它需要的查询头/参数中非常详细,以便允许所需的不同数据库查询(例如此处演示的两个子资源端点的查询)。
这里有更好的解决方案/抽象吗?