Skip to main content

Using Mongoose

Background

You may be wondering why we need to create a separate joi schema when we already have a mongoose schema, and we can validate the data using the mongoose schema. Well, the answer is that we can use the mongoose schema for validation.

What is mongoose?

mongoose is a library that allows us to interact with MongoDB, for that, we need to create a model using mongoose schema. We covered that here

Let's start

Create Project

We will create a project to demonstrate the validation using mongoose.

Create a directory, navigate to it
mkdir express-mongoose-validation

cd express-mongoose-validation

Initialize the project.

npm init -y

Install the dependencies.

npm install express mongoose

Create User Model

Let's create a user model using mongoose.

models/user.js
import mongoose from "mongoose";

export const schema = mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
age: { type: String, min: 18 },
});

export default mongoose.model("User", schema);

Create Middleware

As we did in the previous documentation, we will create a middleware to validate the data.

middlewares/validate.js
const validate = (schema, key) => (req, res, next) => {
const error = new schema(req[key]).validateSync();
if (error) {
res.status(400).send(error);
} else {
// If there's no error, move on to the next middleware
next();
}
};

export default validate;

Create index.js file

Let's create an index.js file and add the following code to it.

index.js
import express from "express";
import mongoose from "mongoose";
import UserModel from "./models/user.js";
import validate from "./middlewares/validate.js";

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const connection = mongoose.connection;
connection.once("connected", () => console.log("Database Connected ~"));
connection.on("error", (error) => console.log("Database Error: ", error));
mongoose.connect("mongodb://localhost:27017/express-validation", {
useNewUrlParser: true,
useUnifiedTopology: true,
});

// See, I am passing the UserModel schema to the validate middleware
app.post("/register", validate(UserModel), async (req, res) => {
try {
const user = await UserModel.create(req.body);
res.send(user);
} catch (error) {
res.status(500).send(error);
}
});

app.listen(2000, () => console.log("Server Started at port 2000"));

Run the Project and Test the API

Let's run the project and test the API.

Run the project
node index.js

Now, open the postman and send a POST request to http://localhost:2000/register with the following data.

Request Body
{
"name": "Muhammad Rizwan Ashiq",
"email": "mrizwanashiq@outlook.com",
"password": "123456",
"age": 17
}

You will get the following response.

Response Body
{
"errors": {
"age": {
"message": "Path `age` (`17`) is less than minimum allowed value (18).",
"name": "ValidatorError",
"properties": {
"message": "Path `age` (`17`) is less than minimum allowed value (18).",
"min": 18,
"path": "age",
"type": "min",
"value": 17
},
"kind": "min",
"path": "age",
"value": 17
}
},
"_message": "User validation failed",
"message": "User validation failed: age: Path `age` (`17`) is less than minimum allowed value (18).",
"name": "ValidationError"
}

Why do we need to create a separate joi schema?

You may be wondering if the mongoose schema could also validate the data, then why do we need to create a separate joi schema?

Joi is often preferred for request validation over Mongoose because it provides a more comprehensive and flexible set of validation capabilities. With Joi, developers have access to a wide range of validation rules and options, allowing them to handle complex input scenarios and enforce stricter data validation requirements. This flexibility empowers developers to implement robust validation logic and ensure the accuracy and integrity of incoming data.

Code

You can download the related code from here

Conclusion

In this documentation, we have learned how to validate the data using mongoose.