在 Mongoose 模型中访问 Express.js 请求上下文

Posted

技术标签:

【中文标题】在 Mongoose 模型中访问 Express.js 请求上下文【英文标题】:Accessing Express.js request context in Mongoose models 【发布时间】:2014-09-19 23:46:40 【问题描述】:

我正在与我的同事一起使用Express.js 和Mongoose 开发一个REST API。

对于某些 Mongoose Model methodsstatics,我们需要 Express.js Request 对象作为添加的上下文信息源,例如当前执行请求的经过身份验证的用户。

我们目前所做的是通过原型化MongooseModel 函数将一个名为context 的自定义属性附加到Modelthis 上下文。

问题是我们遇到了一个令人讨厌的错误,它让我们意识到虽然在 Model 实例上调用 Model.methods 时,它可以正常工作。

对于Model.statics,他们在Model“类”上被调用,该类被实现为singleton,范围由整个应用程序共享,这意味着如果您有并发请求,它们将覆盖每个-如果您在请求处理中有任何异步行为,则为其他人的 this.context 值。

现在我的问题如下:

Express.jsMongooseModel.staticsModel.methods 函数中保留和访问 request 上下文的最佳做法是什么?

当然有一些可能的黑客来模拟收容,例如:

    Function.bind()Model 函数添加请求上下文。

    -> 这意味着如果Model.statics.a() 在内部调用Model.statics.b(),函数b() 将不会有this.context

    request 对象上使用with() 语句并调用该范围内的每个Model 函数。

    -> 这会很脏而且很慢。

    使用 vm 标准 Node.js 模块创建具有单独作用域的容器。

    -> 同(2),性能会受到很大影响。

有什么想法吗?提前谢谢你!

【问题讨论】:

【参考方案1】:

希望你仍然对答案感兴趣

你真正想要的是模仿java的线程本地概念,它基本上允许你在那个线程的上下文中定义一些东西。

Node 是一个单线程环境,除了domains,它不提供类似的东西。域在为特定操作集提供上下文和模拟线程本地存储方面非常有用。

Node js 域很快将被弃用,但类似的解决方案如 continuation-local-storage 在 npm 中可用,这将解决您的目的

例如: 在请求的上下文中创建域

app.use(function(req, res, next) 
    var reqDomain = domain.create();
    reqDomain.run(next);            //here your request context is created
);

现在使用 process.domain,我将能够在任何地方访问绑定到上面创建的域的“数据”

var d = process.domain              //process.domain is always be available to you while serving the request
d.obj = ;

【讨论】:

以上是关于在 Mongoose 模型中访问 Express.js 请求上下文的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mongoose/Express/Node 在一个 POST 路由中保存多个模型文档

从上下文中获取模型与导入 - apollo server express & mongoose

从 Rest(Express) 迁移到 GraphQL:模型(mongoose) 在 graphQL 解析器中不起作用

使用 Mongoose、Express、NodeJS 更新模型

Express App 中的 Mongoose 模型(未被要求找到)

无法通过 express/mongoose/angularjs 从 Mongodb 访问数据