Middleware ========== Middleware are defined at the Schema level and are applied when the methods `init` (when a document is initialized with data from MongoDB), `save`, and `remove` are called on a document instance. There are two types of middleware, serial and parallel. Serial middleware are defined like: schema.pre('save', function (next) { // ... }) They're executed one after the other, when each middleware calls `next`. Parallel middleware offer more fine-grained flow control, and are defined like schema.pre('remove', true, function (next, done) { // ... }) Parallel middleware can `next()` immediately, but the final argument will be called when all the parallel middleware have called `done()`. ## Use cases Middleware are useful for: - Complex validation - Removing dependent documents when a certain document is removed (eg: removing a user removes all his blogposts) - Asynchronous defaults - Asynchronous tasks that a certain action triggers. For example: - Triggering custom events - Creating notifications - Emails and many other things. They're specially useful for atomizing model logic and avoiding nested blocks of async code. ## 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. For example: schema.pre('save', function (next) { // something goes wrong next(new Error('something went wrong')); }); // later... myModel.save(function (err) { // err can come from a middleware });