Lesson 14 of 18

Schema Validation

Built-in Validators

Mongoose provides built-in validators for common checks like required fields, min/max values, and enums.

Example
const productSchema = new Schema({
  name: {
    type: String,
    required: [true, 'Product name is required'],
    minlength: [2, 'Name must be at least 2 characters'],
    maxlength: [100, 'Name cannot exceed 100 characters']
  },
  price: {
    type: Number,
    required: true,
    min: [0, 'Price cannot be negative']
  },
  category: {
    type: String,
    enum: {
      values: ['Electronics', 'Clothing', 'Food'],
      message: '{VALUE} is not a valid category'
    }
  },
  sku: {
    type: String,
    unique: true,
    match: [/^[A-Z]{3}-\d{4}$/, 'SKU must be format XXX-0000']
  }
});

Custom Validators

Create custom validation logic for complex business rules.

Example
const userSchema = new Schema({
  email: {
    type: String,
    validate: {
      validator: function(v) {
        return /^[\w.-]+@[\w.-]+\.\w+$/.test(v);
      },
      message: props => `${props.value} is not a valid email`
    }
  },
  password: {
    type: String,
    validate: {
      validator: function(v) {
        return v.length >= 8;
      },
      message: 'Password must be at least 8 characters'
    }
  }
});

// Middleware (hooks)
userSchema.pre('save', async function(next) {
  if (this.isModified('password')) {
    this.password = await bcrypt.hash(this.password, 10);
  }
  next();
});