I have an API in ExpressJS and a middleware that gets executed before each endpoint controller:
app.use(segregationMiddleware);
app.get('/some-endpoint', controller1);
app.get('/some-endpoint-2', controller2);
The segregationMiddleware is used to look for some parameters in the request and then it calculates a value that then is stored in the request object as req.locals.domain so the controllers can access it.
In each Mongoose model, I define a field named domain using a Mongoose plugin (so I don't have to do it every time). That field is used to segregate my assets. This means that when the segregationMiddleware populates req.locals.domain = 'foo' for example, if I make a model.find({}) I want to get only assets that have { domain: 'foo' }. Same thing if I try to update, save, delete, and so.
Of course, I can just simply modify the query on each controller since I have accesso to req, but I need to do it every time and I need to remember it for finds, findAndUpdate, save, and soo... sooner or later I'm gonna forget it.
I can define some hooks in Mongoose that will modify the query using a plugin so it adds the domain constraint to the query so I don't have to do it in the controller BUT I don't have the current req object in the Mongoose plugin unless I pass it, and the only way that come to my mind is to abstract the DB methods in the plugin, so in the controller, I do something like this:
model.safeFind(req, query);
And in the plugin I define safeFind like:
safeFind = () => {
const theRealQuery = Object.assign({}, query, { domain: req.locals.domain });
return this.find(query);
}
BUT, in this way, I need to redefine each DB query function (find, findOne, update, save...) and I need to remember to use the safe methods. Then again, I'm going to forget it sooner or later.
Is there a way I can still use the regular Mongoose methods from the controller and have the plugin somehow modify the query for every method using the current req object?