title: How to use MongoDB's new Schema Validation feature in Express.js?
body: <p><strong>How do you implement MongoDB's Schema Validation feature in Express server?</strong> I'm working on a simple todo app and decided to use the native MongoClient instead of mongoose but i still do want to have a schema.</p>
  
  <p>Base on MongoDB's docs here: <a href="https://docs.mongodb.com/manual/core/schema-validation/#schema-validation" rel="nofollow noreferrer">https://docs.mongodb.com/manual/core/schema-validation/#schema-validation</a> You can either create a collection with Schema or update an existing collection without schema to have one. The commands are run in the mongo shell, but how do you implement it in express?</p>
  
  <p>So far what i did is make a function that returns the Schema Validation commands and call it on every routes but i get an error saying <strong>db.runCommand is not a function.</strong> </p>
  
  <p><a href="https://i.stack.imgur.com/cZYRG.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cZYRG.jpg" alt="enter image description here"></a></p>
  
  <p>Here's my express server:</p>
  
  <pre><code>const express = require("express");
  const MongoClient = require("mongodb").MongoClient;
  const ObjectID = require("mongodb").ObjectID;
  const dotenv = require('dotenv').config();
  const todoRoutes = express.Router();
  const cors = require("cors");
  const path = require("path");
  const port = process.env.PORT || 4000;
  const dbName = process.env.DB_NAME;
  let db;
  
  const app = express();
  app.use(cors());
  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));
  
  MongoClient.connect(process.env.MONGO_URI,{useNewUrlParser: true},(err,client)=&gt;{
      if(err){
          throw err;
          console.log(`Unable to connect to the databse: ${err}`);
      } else {
          db =  client.db(dbName);
          console.log('Connected to the database');
      }
  });
  
  /* Schema Validation Function */
  const runDbSchemaValidation = function(){
      return db.runCommand( {
          collMod: "todos",
          validator: { $jsonSchema: {
             bsonType: "object",
             required: [ "description", "responsible","priority", "completed" ],
             properties: {
                description: {
                   bsonType: "string",
                   description: "must be a string and is required"
                },
                responsibility: {
                   bsonType: "string",
                   description: "must be a string and is required"
                },
                priority: {
                  bsonType: "string",
                  description: "must be a string and is required"
               },
               completed: {
                  bsonType: "bool",
                  description: "must be a either true or false and is required"
               }
             }
          } },
          validationLevel: "strict"
       } );
  }
  
  /* Get list of Todos */
  todoRoutes.route('/').get((req,res)=&gt;{
      runDbSchemaValidation();
      db.collection("todos").find({}).toArray((err,docs)=&gt;{
          if(err)
              console.log(err);
          else {
              console.log(docs);
              res.json(docs);
          }
      });
  });
  
  /* Get Single Todo */
  todoRoutes.route('/:id').get((req,res)=&gt;{
      let todoID = req.params.id;
      runDbSchemaValidation();
      db.collection("todos").findOne({_id: ObjectID(todoID)}, (err,docs)=&gt;{
          if(err)
              console.log(err);
          else {
              console.log(docs);
              res.json(docs);
          }
      });
  });
  
  /* Create Todo */
  todoRoutes.route('/create').post((req,res,next)=&gt;{
      const userInput = req.body;
      runDbSchemaValidation();
      db.collection("todos").insertOne({description:userInput.description,responsible:userInput.responsible,priority:userInput.priority,completed:false},(err,docs)=&gt;{
          if(err)
              console.log(err);
          else{
              res.json(docs);
          }
      });
  });
  
  /* Edit todo */
  todoRoutes.route('/edit/:id').get((req,res,next)=&gt;{
      let todoID = req.params.id;
      runDbSchemaValidation();
      db.collection("todos").findOne({_id: ObjectID(todoID)},(err,docs)=&gt;{
          if(err)
              console.log(err);
          else {
              console.log(docs);
              res.json(docs);
          }
      });
  });
  
  todoRoutes.route('/edit/:id').put((req,res,next)=&gt;{
      const todoID = req.params.id;
      const userInput = req.body;
      runDbSchemaValidation();
      db.collection("todos").updateOne({_id: ObjectID(todoID)},{ $set:{ description: userInput.description, responsible: userInput.responsible, priority: userInput.priority, completed: userInput.completed }},{returnNewDocument:true},(err,docs)=&gt;{
          if(err)
              console.log(err);
          else
              res.json(docs);
          console.log(db.getPrimaryKey(todoID));
      });
  });
  
  /* Delete todo */
  todoRoutes.route('/:id').delete((req,res,next)=&gt;{
      const todoID = req.params.id;
      runDbSchemaValidation();
      db.collection("todos").deleteOne({_id: ObjectID(todoID)},(err,docs)=&gt;{
          if(err)
              console.log(err)
          else{
              res.json(docs);
          }
      });
  });
  
  app.use('/todos',todoRoutes);
  
  app.listen(port,()=&gt;{
      console.log(`Server listening to port ${port}`);
  });
  </code></pre>
  
  <p>I also tried it on the initial client connection but i got the same error: 
  <a href="https://i.stack.imgur.com/tMZtY.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/tMZtY.jpg" alt="enter image description here"></a></p>