在发送到Mongoose的客户端之前操作查询的数据库文档被认为是不好的做法吗?

时间:2015-05-08 03:43:20

标签: node.js mongodb express

所以我花了很长时间试图弄清楚如何使用转换和虚拟操作返回的数据库文档(使用mongoose),但就我的目的而言,这些都不是选项。我想要的行为非常类似于转换(我删除属性),但我只想从返回的文档中删除属性IFF它满足使用req.session.user / req.user计算的需求。对象(我使用PassportJS,但任何等效的会话用户就足够了)。显然,虚拟或转换中无法访问请求对象,因此我无法进行计算。

然后我突然意识到,在将其发送到客户端之前,我可以正常查询并操纵回调中的返回对象。而且我可以把它放在一个看起来不错的中间件功能中,但有些东西告诉我这是一个hacky事情。我向客户端呈现了一个api,它不反映直接从数据库中存储/检索的数据。如果我有这样的中间件使得维护代码变得更加困难,它也可能会混乱我的路由配置。下面是操作的示例:

app.route('/api/items/:id').get(manipulateItem, sendItem);
app.param('id', findUniqueItem);

function findUniqueItem(req, res, next, id) {
    Item.findUniqueById(id, function(err, item) {
        if (!err) { req.itemFound = item; }
        next();
    }
}

function manipulateItem(req, res, next) {
    if (req.itemFound.people.indexOf(req.user) === -1) {
        req.itemFound.userIsInPeopleArray = false;
    } else {
        req.itemFound.userIsInPeopleArray = true;
    }
    delete req.itemFound.people;
}

function sendItem(req, res, next) {
    res.json(req.itemFound);
}

我觉得这是一个解决方案,解决了更简单的解决方案,但我不确定解决方案是什么。

1 个答案:

答案 0 :(得分:1)

对修改它的行为没有任何苛刻 修改它时,这都是的问题。

对于玩具服务器和学习项目,答案就是随时随地 在生产环境中,您希望在离开系统的过程中进行转换,然后进入下一个系统(下一个系统可能是最终用户;它可能是另一个服务器;它可能是您自己的另一个大功能块服务器,不应该可以访问完成其工作所需的更多信息。)

getItemsFromSomewhere()
  .then(transformToTypeICanUse)
  .then(filterBasedOnMyExpectations)
  .then(doOperations)
  .then(transformToTypeIPromisedYou)
  .then(outputToNextSystem);

对于实际的 how 而言,这个例子可能不是非常有用,但这就是重点。
正如您所看到的,您可以将事件系统链接到另一个事件系统(它自己转换为自己的数据结构,执行自己的过滤/映射,将数据转换为其API承诺的任何内容,并将其传递给它一直到下一个系统,最终到最终用户)。

我认为部分是" hacking"来自将异步流程的结果用螺栓连接到req,其中req通过中间件逐步注入。{/ p>

那说:

function eq (a) {
  return function (b) { return a === b; };
}

function makeOutputObject (inputObject, personWasFound) {
  // return whatever you want
}

var personFound = req.itemFound.people.some(eq(req.user));
var outputObject = makeOutputObject(req.itemFound, personFound);

现在您没有使用实际的delete关键字,也没有修改该itemFound对象的号召性呼叫状态。

您将基于视图的逻辑与基于应用的逻辑分开,但没有正式的障碍(如果需要,可以随后添加)。