简体   繁体   中英

Accessing Express.js request context in Mongoose models

I am developing a REST API with my colleagues using Express.js and Mongoose .

For some of the Mongoose Model methods and statics we need the Express.js Request object as an added context information source, like the authenticated user currently doing the request.

What we currently do is attach a custom property called context to a Model 's this context by prototyping Mongoose 's Model function.

The issue is that we ran into a nasty bug that made us realise that while with Model.methods , who are called on Model instances, it works fine.

For Model.statics , who are called on the Model "class" which is implemented as a singleton though, the scope is shared by the whole app meaning that if you have concurrent requests, they will override each-other's this.context value if you have any async behaviour in the request processing.

Now my question is the following:

  • What are the best practices with Express.js and Mongoose for keeping and accessing the request context in Model.statics and Model.methods functions ?

Of course there are some possible hacks to simulate containment like:

  1. Function.bind() every Model function to add the request context.

    -> This would mean though that if Model.statics.a() internally makes a call to Model.statics.b() , function b() wouldn't have a this.context .

  2. Use the with() {} statement on the request object and call every Model function within that scope.

    -> Which would be pretty dirty and slow.

  3. Create containers with separate scopes with the vm standard Node.js module.

    -> Same as (2), performance would take a big hit.

Any ideas ? Thank you in advance !

Hope you are still interested in the answer

What you really want is to mimic java's thread local concept which basically allows you to define something in the context of that thread.

Node is a single threaded environment and it does not provide anything like that but domains . Domains are very useful in providing context for particular set of operations and mimicking thread local storage.

Node js domains will soon be deprecated but similar solutions like continuation-local-storage are available in npm which will solve your purpose

Eg: Create domain in the context of request

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

Now with the use of process.domain, I will be able to access 'data' bound to above created domain anywhere

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM