在 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
methods
和 statics
,我们需要 Express.js
Request
对象作为添加的上下文信息源,例如当前执行请求的经过身份验证的用户。
我们目前所做的是通过原型化Mongoose
的Model
函数将一个名为context
的自定义属性附加到Model
的this
上下文。
问题是我们遇到了一个令人讨厌的错误,它让我们意识到虽然在 Model
实例上调用 Model.methods
时,它可以正常工作。
对于Model.statics
,他们在Model
“类”上被调用,该类被实现为singleton
,范围由整个应用程序共享,这意味着如果您有并发请求,它们将覆盖每个-如果您在请求处理中有任何异步行为,则为其他人的 this.context
值。
现在我的问题如下:
Express.js
和 Mongoose
在 Model.statics
和 Model.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 更新模型