Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

82 lines (74 sloc) 2.999 kb
extends layout
block content
h2 Middleware
:markdown
Middleware are functions which are passed control of flow during execution of [init](./api.html#document_Document-init), [validate](./api.html#document_Document-validate), [save](./api.html#model_Model-save) and [remove](./api.html#model_Model-remove) methods. There are two types of middleware, `pre` and [post](#post). Let's start with `pre`.
h3 Pre
:markdown
There are two types of `pre` middleware, serial and parallel.
h4 Serial
:markdown
Serial middleware are executed one after another, when each middleware calls `next`.
:js
var schema = new Schema(..);
schema.pre('save', function (next) {
// do stuff
next();
});
h4 Parallel
p
| Parallel middleware offer more fine-grained flow control.
:js
var schema = new Schema(..);
schema.pre('save', true, function (next, done) {
// calling next kicks off the next middleware in parallel
next();
doAsync(done);
});
:markdown
The hooked method, in this case `save`, will not be executed until `done` is called by each middleware.
h4 Use Cases
p
| Middleware are useful for atomizing model logic and avoiding nested blocks of async code. Here are some other ideas:
ul
li complex validation
li
| removing dependent documents
ul
li (removing a user removes all his blogposts)
li asynchronous defaults
li asynchronous tasks that a certain action triggers
ul
li triggering custom events
li notifications
h4 Error handling
:markdown
If any middleware calls `next` or `done` with an `Error` instance, the flow is interrupted, and the error is passed to the callback.
:js
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
});
h3#post Post middleware
:markdown
[post](/docs/api.html#schema_Schema-post) middleware are executed _after_ the hooked method and all of its `pre` middleware have completed. `post` middleware do not directly receive flow control, e.g. no `next` or `done` callbacks are passed to it. `post` hooks are a way to register traditional event listeners for these methods.
:js
schema.post('init', function (doc) {
console.log('%s has been initialized from the db', doc._id);
})
schema.post('validate', function (doc) {
console.log('%s has been validated (but not saved yet)', doc._id);
})
schema.post('save', function (doc) {
console.log('%s has been saved', doc._id);
})
schema.post('remove', function (doc) {
console.log('%s has been removed', doc._id);
})
h3#next Next Up
:markdown
Now that we've covered `middleware`, let's take a look at Mongooses approach to faking JOINs with its query [population](/docs/populate.html) helper.
Jump to Line
Something went wrong with that request. Please try again.