Middleware
Middleware are functions which are passed control of flow during execution of init, validate, save and remove methods.
There are two types of middleware, serial and parallel.
Serial
Serial middleware are executed one after another, when each middleware calls next
var schema = new Schema(..);
schema.pre('save', function (next) {
// do stuff
next();
});
Parallel
Parallel middleware offer more fine-grained flow control.
var schema = new Schema(..);
schema.pre('save', true, function (next, done) {
// calling next kicks off the next middleware in parallel
next();
doAsync(done);
});
The hooked method, in this case save
, will not be executed until done
is called by each middleware.
Use Cases
Middleware are useful for atomizing model logic and avoiding nested blocks of async code. Here are some other ideas:
- complex validation
- removing dependent documents
- (removing a user removes all his blogposts)
- asynchronous defaults
- asynchronous tasks that a certain action triggers
- triggering custom events
- notifications
Error handling
If any middleware calls next
or done
with an Error
instance, the flow is interrupted, and the error is passed to the callback.
schema.pre('save', function (next) {
var err = new Error('something went wrong');
next(err);
});
// later...
myModel.save(function (err) {
console.log(err.message) // something went wrong
});
Next Up
Now that we've covered middleware
, let's take a look at Mongooses approach to faking JOINs with its query population helper.