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.
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.
mkdir express-mongoose-validation
cd express-mongoose-validation
Initialize the project.
- npm
- Yarn
- pnpm
- Bun
npm init -y
yarn init -y
pnpm init -y
bun init -y
Install the dependencies.
- npm
- Yarn
- pnpm
- Bun
npm install express mongoose
yarn add express mongoose
pnpm add express mongoose
bun add express mongoose
Create User Model
Let's create a user model using mongoose.
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.
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.
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.
node index.js
Now, open the postman and send a POST request to http://localhost:2000/register with the following data.
{
"name": "Muhammad Rizwan Ashiq",
"email": "mrizwanashiq@outlook.com",
"password": "123456",
"age": 17
}
You will get the following response.
{
"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.