Mongoose Schema Middleware

This post is about making Schema middelware using mongoose as a mongodb client. Making such middleware for a schema is useful for preforming certain tasks such as sanitation, and producing certain values that are the result of a method before creating or updating a document. For example I could have a user model that has some middleware that makes sure that a username does not violate certain rules before continuing, rules like the username must begin with a letter, only contain permitted characters, and not exceed a set character length.

1 - what to know

This post is about mongoose middleware functions that act on a Schema that are used when making a model. It is not a post on models in general with mongoose, or mongodb in general. I also assume that you have a basic working knowledge of node.js, JavaScript, and other skills necessary to get anything of value from this post.

2 - An example of a schema level middleware in mongoose that involves Orbs.

I just started working on a project that will be the first of maybe a few mean stack application examples for this site. I thought that it would be nice to make at least one or two projects that are fun, so I can really get into it. So for an example of mongoose Shemea middlewareI will write about the current state of what will become one of several models that will be used in a game prototype that I am making that has to do with what I am calling Orbs.

I will not bore you with the details but for the sake of this post I want to have it so that every Orb will have an owner, and that owner will be the username that currently owns that Orb. So I can use a Shema middleware to make sure that the Orb has an owner before continuing with it’s creation.

2.1 - The Orb Model

I start creating my Model by pulling in mongoose with require, and then referencing the Schema constructor. Once I have that I create a Schema for my model with the Schema constructor, I can then define a pre middleware by calling the pre method of the Schema instance, followed by the document function I want to make the middleware for, and then the function that defines the middleware.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// grab mongoose
let mongoose = require('mongoose'),
Schema = mongoose.Schema;
// Schema
let OrbSchema = new Schema({
points: {type: Array, default:[]},
owner: {type: String, default: '_none'}
});
// an orb must belong
OrbSchema.pre('save', function (next) {
let e = null;
if(this.owner === '_none' || !this.owner){
e = new Error('The Orb must have an Owner')
}
console.log(this);
next(e);
});
// The Orb Model
let Orb = mongoose.model('Orb', OrbSchema);
// export it
module.exports = Orb;

So with this example creating an Orb will result in an error if a username of ‘_none’ which is the default for the current User model, or if the owner name results in false for any reason when converter to a boolean. I could also have it check if the user exists, which would be even better, but you get the idea, these hooks are very useful for these kinds of checks.

3 - Conclusion

Mongoose Schema Middleware functions are a great way to set up a bunch of sanitation checks, and other tasks that should happen with respect to certain actions that happen with mongodb collections. For example in this project that I am making I would want all the orbs of a player to be deleted if the user is deleted, that can be done with these methods.