{"id":18057,"date":"2021-05-08T08:23:04","date_gmt":"2021-05-08T08:23:04","guid":{"rendered":"https:\/\/www.bacancytechnology.com\/blog\/?p=18057"},"modified":"2024-11-13T07:16:14","modified_gmt":"2024-11-13T07:16:14","slug":"joi-validation-in-nodejs-and-express","status":"publish","type":"post","link":"https:\/\/www.bacancytechnology.com\/blog\/joi-validation-in-nodejs-and-express","title":{"rendered":"API Request Schema With Joi Validation in NodeJS and Express"},"content":{"rendered":"<style>\nul.index-list {\n    text-align: left;\n    list-style-type: square;\n}\np{\n   width:100%;\n}\n.post-content p img {\n    margin-bottom: 0 !important;\n}\n.text-orange,.text-orange> strong{\ncolor: #ec6100 !important;\nfont-weight: 700;\n}\n.border-box{\npadding: 12px;\nborder: 1px solid #000;\nmargin-bottom: 16px;\n}\n.border-div{border: 1px solid #000; padding: 22px; text-align: center; margin-bottom: 32px;}\n\t\t.border-bottom{\n\t\t\tborder-bottom: 1px solid #000;\n\t\t\ttext-align: center;\n\t\t\tdisplay: inline-block;\n\t\t}\n\t\t.border-div p{text-align: left;}\n\t\t.cust-list{padding: 0; text-align: left;}\n\t\t.cust-list li{padding-left: 32px; list-style: none}\npre {\n    background: #f7e9dd;\n    border: none;\n    font-size: 16px;\n}\n.cross-platform{\n    background: #f7e9dd;\n    border: none;\n    font-size: 20px;\n    text-align:center;\n    padding:40px;\n}\n.cross-platform a{\n   font-size: 20px !important;\n    font-weight: bold !important;\n    margin-top: 10px;\n    border-radius: 10px !important;\n    background: #ec6100 !important;\n    border: 1px solid transparent !important;\n}\n.final{\n    background: #f7e9dd;\n    border: none;\n    font-size: 20px;\n    text-align:left;\n    padding:40px;\n}\n.final a{\n   font-size: 20px !important;\n    font-weight: bold !important;\n    margin-top: 10px;\n    border-radius: 10px !important;\n    border: 1px solid transparent !important;\n}\n<\/style>\n<p><em>Assume you\u2019re working on an endpoint that expects user data such as \u2013 username, age, address, pin code, state, and phone number. Consider a user entering numeric data for the username by mistake when you\u2019re expecting alphabetic data; a user entering an invalid pin code or birthdate for their respective fields when you\u2019re expecting the data in a particular format. You don\u2019t wish to make undesirable data! So, you can go for Data Validation to make sure that the data you receive is in a proper format. And for validating your data, you can either choose a manual way of coding the whole logic or use a validation library\/package.<\/em><\/p>\n<p><em>In this tutorial, we will learn about how to use joi validation in node js and Express. For your better understanding, I have divided the entire tutorial of joi validation in node js example into various sections.<\/em><\/p>\n<h2>What is Joi?<\/h2>\n<p>Joi is the most famous, efficient, and widely used package for object schema descriptions and validation. Joi allows the developers to build the Javascript blueprints and make sure that the application accepts the accurately formatted data.<\/p>\n<p>Here are some of the advantages of Joi-<\/p>\n<ul class=\"bullets text-left\">\n<li>Easy to implement and easy to learn.<\/li>\n<li>Widely accepted and well-known package for data validation.<\/li>\n<li>Supports validation based on the schema.<\/li>\n<\/ul>\n<p>Let us start with creating a simple demo application for <b>joi validation<\/b> in node js and joi express validation.<\/p>\n<h2>Steps to implement API Request Schema with Joi Validation In Node.js and Express.<\/h2>\n<h3>Step 1: Initial Setup<\/h3>\n<p>Create a directory that is our root directory<\/p>\n<pre>mkdir JoiValidation\r\ncd JoiValidation<\/pre>\n<h3>Step 2:Define package.json file<\/h3>\n<p>For creating one, run this command:<\/p>\n<pre>npm init<\/pre>\n<h3>Step 3: Install dependencies<\/h3>\n<p>We have five dependencies to be installed for Joi file Validation:<\/p>\n<ul class=\"bullets text-left\">\n<li>bcryptjs<\/li>\n<li>body-parser<\/li>\n<li>dotenv <\/li>\n<li>express <\/li>\n<li>joi <\/li>\n<li>mongoose<\/li>\n<\/ul>\n<p>Run this command to install all the dependencies mentioned above.<\/p>\n<pre>npm install --save bcryptjs dotenv express joi mongoose<\/pre>\n<p>1. <strong>bcryptjs<\/strong>: It is used for storing plaintext password into hashing password for security purposes. <\/p>\n<p>2. dotenv: A module with no dependency. It is used for loading the environment variables from a .env file into the process .env. <\/p>\n<p>3. express: It is a well-known and flexible Node.js framework for developing web applications. It offers robust features for building web\/mobile applications. <\/p>\n<p>4. joi: It is an object schema description language that validates JS objects. With Joi, we can quickly build schemas for JS objects and make sure to validate critical data. <\/p>\n<p>5. mongoose: It is a tool for MongoDB object modelling, which is designed to work in an async environment.<\/p>\n<h3>Step 4: Create Server and Connect with Database<\/h3>\n<p>Creating a <em>.env file<\/em> in the root directory for storing our environment variables.<\/p>\n<p>In the <em>.env file<\/em>, we need to create two variables &#8211; the first is the <strong>PORT<\/strong>, and another is <strong>MONGO_URI<\/strong>, for your database connection.<br \/>\nThen,  provide appropriate value for both the variables.<\/p>\n<p>Once you\u2019re done with that, create a folder <strong>src<\/strong> in the root directory. It will contain various folders like <em>controllers, models, db, routes<\/em> and <em>utils<\/em>. We will cover on later.<\/p>\n<p class=\"boxed bg--secondary\" style=\"border: 1px solid #c7c7c7; box-shadow: 0 0 40px rgba(0, 0, 0, 0.2);\"><strong><i><span style=\"font-size:22px; color:#000;\">Are you in need of a skilled Node.js developers to build and maintain your web applications?<\/span><br \/>\nLook no further! Our team of experienced Node.js developers are ready to provide top-notch services for your business needs. <a href=\"https:\/\/www.bacancytechnology.com\/hire-node-developer\" target=\"_blank\" rel=\"noopener\">Hire Node js developer<\/a> today and get your application running smoothly again.<\/i><\/strong><\/p>\n<h3>Step 5: Creating Connection file<\/h3>\n<p>In the <strong>db<\/strong> folder, we will create a conn.js file and write code for database connection.<\/p>\n<p><strong>conn.js<\/strong><\/p>\n<pre>const mongoose = require('mongoose');\r\n\r\nmongoose.connect(process.env.MONGO_URI, {\r\n    useNewUrlParser: true,\r\n    useUnifiedTopology: true\r\n}).then(() => {\r\n    console.log('Connection successful!');\r\n}).catch((e) => {\r\n    console.log('Connection failed!');\r\n})<\/pre>\n<p>In <em>conn.js<\/em>, we need to require a <em>mongoose<\/em> package to connect with the MongoDB database.<br \/>\n<strong>connect()<\/strong> function takes two arguments &#8211; first is <em>uri<\/em>, and another is <em>options<\/em>.<br \/>\nWe will get <strong>MONGO_URI<\/strong> from the <em>.env<\/em> file.<\/p>\n<h3>Step 6: Creating server file<\/h3>\n<p>Create a <strong>server.js<\/strong> file in the <em>src<\/em> folder<\/p>\n<p><strong>server.js<\/strong><\/p>\n<pre>require(\"dotenv\").config();\r\nrequire('.\/db\/conn');\r\nconst express = require(\"express\");\r\n\r\nconst app = express();\r\nconst port = process.env.PORT;\r\n\r\napp.use(express.json({ limit: \"10MB\" }));\r\napp.use(express.urlencoded({ extended: true }));\r\n\r\napp.listen(port, () => {\r\nconsole.log(`Server is running at ${port}`);\r\n});\r\n<\/pre>\n<p>Once we are done with the initialising of <em>const express<\/em>, we will further use <strong>json()<\/strong> and <strong>urlencoded()<\/strong> to parse JSON data from the request body and urlencoded bodies. Now, we will check whether our connection is established or not.<br \/>\nTo run the server, we have to add two scripts in the <strong>package.json<\/strong> file.<br \/>\n<strong>package.json<\/strong><\/p>\n<pre>\"dev\": \"nodemon src\/server.js\",\r\n\"start\": \"node src\/server.js\"\r\n<\/pre>\n<p><strong>dev <\/strong>\u2013 for pre-installed nodemon in your system.<br \/>\n<strong>start <\/strong>\u2013 for running server without nodemon.<br \/>\nTest your connection by running this command:<\/p>\n<pre>npm start<\/pre>\n<p>The message displayed in your terminal is given below.<\/p>\n<p class=\"boxed bg--secondary\" style=\"border: 1px solid #c7c7c7; box-shadow: 0 0 40px rgba(0, 0, 0, 0.2);\"><strong>Server is running at 3000<br \/>\nConnection successful!<\/strong><\/p>\n<p>So, the connection has been established successfully!<\/p>\n<h3>Step 7: Creating Home Route<\/h3>\n<p>Inside the <em>utils<\/em> folder, we will create an<strong> errorFunction.js<\/strong> file for creating <strong>errorFunction()<\/strong> to display error messages and data in JSON format.<br \/>\n<strong>errorFunction.js<\/strong><\/p>\n<pre>const errorFunction = (errorBit, msg, data) => {\r\n     if (errorBit) return { is_error: errorBit, message: msg };\r\n     else return { is_error: errorBit, message: msg, data };\r\n};\r\n\r\nmodule.exports = errorFunction;<\/pre>\n<p>errorFunction() takes three arguments \u2013<br \/>\n1. <strong>errorBit<\/strong> \u2013 for checking if the error has occurred or not,<br \/>\n2. <strong>msg<\/strong> \u2013 for displaying appropriate messages for which action is performed,<br \/>\n3. <strong>data<\/strong>\u2013 sent to the user. <\/p>\n<p>Whenever an error occurs, it will return \u2013 errorBit and msg or else errorBit, msg and data.<br \/>\nWhenever an error occurs, it will return \u2013 <strong>errorBit<\/strong> and <strong>msg<\/strong> or else <strong>errorBit<\/strong>, <strong>msg<\/strong> and <strong>data<\/strong>.<\/p>\n<h3>Step 8: Creating controller<\/h3>\n<p>In controllers, we need to create the <strong>defaultController.js<\/strong> file.<br \/>\n<strong>defaultController.js<\/strong><\/p>\n<pre>const errorFunction = require(\".\/..\/utils\/errorFunction\");\r\n\r\nconst defaultController = async (req, res, next) => {\r\nres.status(200);\r\nres.json(errorFunction(false, \"Home Page\", \"Welcome from Bacancy\"));\r\n};\r\n\r\nmodule.exports = defaultController;\r\n<\/pre>\n<p>Create a defaultController variable for sending a JSON response to the user. It sends three arguments \u2013<br \/>\n1. false will be the errorBit<br \/>\n2. \u201cHome Page\u201d will be a message<br \/>\n3. \u201cWelcome from Bacancy\u201d will be data. <\/p>\n<p>And then export the defaultController variable.<\/p>\n<h3>Step 9: Creating Route<\/h3>\n<p>Inside the <em>routes<\/em> folder, we need to create the <strong>userRoute.js<\/strong> file<\/p>\n<p><strong>userRoute.js<\/strong><\/p>\n<pre>const express = require(\"express\");\r\nconst defaultController = require(\"..\/controllers\/defaultController\");\r\n\r\nconst router = express.Router();\r\n\r\nrouter.get(\"\/\", defaultController);\r\n\r\nmodule.exports = router;\r\n<\/pre>\n<p>Create a <strong>router<\/strong> variable for creating <em>get<\/em> or <em>post<\/em> requests. Here, we will create a <em>get<\/em> request for a <em>home<\/em> route.<\/p>\n<p>In the <strong>server.js<\/strong> file,  add the following lines to use the <em>router<\/em>. <\/p>\n<pre>const userRoutes = require(\".\/routes\/userRoutes\");\r\napp.use('\/', userRoutes);\r\n<\/pre>\n<h3>Step 10: Testing Home API in Postman<\/h3>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/TSv2w190dbk\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h3>Step 11: Creating User Model<\/h3>\n<p>Now, it\u2019s time to create a user model for storing user schema. Inside the <em>models<\/em> folder, create a <strong>user.js<\/strong> file.<br \/>\n<strong>user.js<\/strong><\/p>\n<pre>const mongoose = require(\"mongoose\");\r\nconst userSchema = new mongoose.Schema(\r\n{\r\n\tuserName: {\r\n\t\ttype: String,\r\n\t\trequired: true,\r\n\t\ttrim: true,\r\n\t},\r\n\r\n\r\n\temail: {\r\n\t\ttype: String,\r\n\t\trequired: true,\r\n\t\ttrim: true,\r\n\t},\r\n\tpassword: {\r\n\t\ttype: String,\r\n\t\trequired: true,\r\n\t\ttrim: true,\r\n\t},\r\n\tmobileNumber: {\r\n\t\ttype: String,\r\n\t\tmaxlength: 10,\r\n\t\trequired: true,\r\n\t},\r\n\tbirthYear: {\r\n\t\ttype: Number,\r\n\t\tmax: 2000,\r\n\t\tmin: 1900,\r\n\t},\r\n\tskillSet: {\r\n\t\ttype: Array,\r\n\t\tdefault: [],\r\n\t},\r\n\tis_active: {\r\n\t\ttype: Boolean,\r\n\t\tdefault: true,\r\n\t},\r\n},\r\n{ timestamps: true }\r\n);\r\n\r\nconst User = mongoose.model(\"user\", userSchema);\r\n\r\nmodule.exports = User;\r\n<\/pre>\n<p>We require a <strong>mongoose<\/strong> package to write a user schema,  a <strong>model()<\/strong> method to create a user model into our database.<\/p>\n<p>We require a mongoose package to write a user schema, a model() method to create a user model into our database. The model() method, \u201cuser,\u201d will be the model name and userSchema will be our userSchema variable. For storing hashing passwords into the database, we will create a securePassword() function. In the utils folder, create securePassword.js file. <\/p>\n<p><strong>securePassword.js<\/strong><\/p>\n<pre>const bcrypt = require(\"bcryptjs\");\r\n\r\nconst securePassword = async (password) => {\r\n    const salt = await bcrypt.genSalt(10);\r\n    const hashedPassword = await bcrypt.hash(password, \tsalt);\r\n    return hashedPassword;\r\n};\r\nmodule.exports = securePassword;\r\n<\/pre>\n<p>Here, we will use the <strong>bcryptjs<\/strong> package for hashing the password.<br \/>\nCreate <strong>securePassword()<\/strong> function for password hashing. It takes one argument, which is a plaintext password. This function will return a hashed password.<\/p>\n<p>Now, we need to create user payload validation using the <strong>joi<\/strong> package.<br \/>\nCreate a <strong>user<\/strong> folder into the <strong>controllers<\/strong> folder. Inside the <strong>user<\/strong> folder, we need to create <strong>user.validator.js<\/strong> for user payload validation.<\/p>\n<p><strong>user.validator.js<\/strong><\/p>\n<pre>const joi = require(\"joi\");\r\nconst errorFunction = require(\"..\/..\/utils\/errorFunction\");\r\n\r\nconst validation = joi.object({\r\n     userName: joi.string().alphanum().min(3).max(25).trim(true).required(),\r\n     email: joi.string().email().trim(true).required(),\r\n     password: joi.string().min(8).trim(true).required(),\r\n     mobileNumber: joi.string().length(10).pattern(\/[6-9]{1}[0-9]{9}\/).required(),\r\n     birthYear: joi.number().integer().min(1920).max(2000),\r\n     skillSet: joi.array().items(joi.string().alphanum().trim(true))\r\n.default([]),\r\n    is_active: joi.boolean().default(true),\r\n});\r\n<\/pre>\n<p>In user.validator.js we require the joi package for payload validation and errorFunction() for JSON response. To create schema object validation, we will use the object() function of joi. We have various properties to validate. Each property needs joi chaining function to validate.<\/p>\n<p>Here are some of the joi functions which we used to validate property.<\/p>\n<p><strong>1. Joi.string():<\/strong> It validates that all properties are string<br \/>\n<strong>2. Joi.alphanum():<\/strong> It must contain only alphanumeric characters.<br \/>\n<strong>3. Joi.min():<\/strong> It specifies the minimum number.<br \/>\n<strong>4. Joi.max():<\/strong> It specifies the maximum number.<br \/>\n<strong>5. Joi.trim():<\/strong> Requires the string value to contain no whitespace before or after.<br \/>\n<strong>6. Joi.required():<\/strong> Make a property required which will not allow undefined as value.<br \/>\n<strong>7. Joi.email():<\/strong> It validates that the email property contains a valid email address.<br \/>\n<strong>8. Joi.length():<\/strong> It specifies the exact number of character or number of items in the array.<br \/>\n<strong>9. Joi.pattern():<\/strong> A pattern will be a regular expression. It specifies validation rules for matching a pattern.<br \/>\n<strong>10. Joi.integer():<\/strong> Requires the number to be an integer (no floating point). <strong><br \/>\n<strong>11. Joi.array():<\/strong> Generates a schema object that matches an array data type.<br \/>\n<strong>12. Joi.items():<\/strong> Lists the types allowed for the array values were types \u2013 one or more joi schema objects to validate each array item against.<br \/>\n<strong>13. Joi.default():<\/strong> creates a default value for property.<br \/>\n<strong>14. Joi.boolean():<\/strong> Generates a schema object that matches a boolean data type (as well as the strings \u2018true\u2019, \u2018false\u2019, \u2018yes\u2019, and \u2018no\u2019). <\/p>\n<p>After that, we will create a middleware function for validating users payload.<\/p>\n<pre>const userValidation = async (req, res, next) => {\r\n\tconst payload = {\r\n\t\tuserName: req.body.userName,\r\n\t\temail: req.body.email,\r\n\t\tpassword: req.body.password,\r\n\t\tmobileNumber: req.body.mobileNumber,\r\n\t\tbirthYear: req.body.birthYear,\r\n\t\tskillSet: req.body.skillSet,\r\n\t\tis_active: req.body.is_active,\r\n\t};\r\n\r\n\tconst { error } = validation.validate(payload);\r\n\tif (error) {\r\n\t\tres.status(406);\r\n\t\treturn res.json(\r\n\t\t\terrorFunction(true, `Error in User Data : ${error.message}`)\r\n\t\t);\r\n\t} else {\r\n\t\tnext();\r\n\t}\r\n};\r\nmodule.exports = userValidation;\r\n<\/pre>\n<p>Here <strong>userValidation<\/strong> is a middleware to validate users payload. We will create a payload variable for storing request data. Now, use <em>validate()<\/em> function to validate users\u2019 payload. <\/p>\n<p>If any error occurred while validating the payload, it displays an error message with status code 406. If no error occurred, then it calls the next() function.<\/p>\n<h3>Step 12: Adding user into the database<\/h3>\n<p>Write the following code in the <strong>user.controller.js<\/strong> file inside the <em>user<\/em> folder.<\/p>\n<p><strong>user.controller.js<\/strong><\/p>\n<pre>const User = require(\"..\/..\/models\/user\");\r\nconst errorFunction = require(\"..\/..\/utils\/errorFunction\");\r\nconst securePassword = require(\".\/..\/..\/utils\/securePassword\");\r\n\r\nconst addUser = async (req, res, next) => {\r\n\ttry {\r\n\t\tconst existingUser = await User.findOne({\r\n\t\t\temail: req.body.email,\r\n\t\t}).lean(true);\r\n\t\tif (existingUser) {\r\n\t\t\tres.status(403);\r\n\t\t\treturn res.json(errorFunction(true, \"User Already Exists\"));\r\n\t\t\t} else {\r\n\t\t\t\tconst hashedPassword = await securePassword(req.body.password);\r\n\t\t\t\tconst newUser = await User.create({\r\n\t\t\t\t\tuserName: req.body.userName,\r\n\t\t\t\t\temail: req.body.email,\r\n\t\t\t\t\tpassword: hashedPassword,\r\n\t\t\t\t\tmobileNumber: req.body.mobileNumber,\r\n\t\t\t\t\tbirthYear: req.body.birthYear,\r\n\t\t\t\t\tskillSet: req.body.skillSet,\r\n\t\t\t\t\tis_active: req.body.is_active,\r\n\t\t\t});\r\n\t\t\tif (newUser) {\r\n\t\t\t\tres.status(201);\r\n\t\t\t\treturn res.json(\r\n\t\t\t\t\terrorFunction(false, \"User Created\", newUser)\r\n\t\t\t\t);\r\n\t\t\t} else {\r\n\t\t\t\tres.status(403);\r\n\t\t\t\treturn res.json(errorFunction(true, \"Error Creating User\"));\r\n\t\t\t}\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tres.status(400);\r\n\t\tconsole.log(error);\r\n\t\treturn res.json(errorFunction(true, \"Error Adding user\"));\r\n\t}\r\n};\r\n<\/pre>\n<p>We need a <strong>User<\/strong> model to add data into the database, <strong>errorFunction()<\/strong>, and <strong>securePassword()<\/strong>.<\/p>\n<p>Inside the <strong>addUser()<\/strong> function, first, we need to check if the user already exists or not. If a user exists then, it will display an error message; otherwise, move further.<br \/>\nNow, use the <strong>create()<\/strong> function to insert data into the database.<\/p>\n<p>If a user is created, it will display a <strong>\u201cuser created\u201d<\/strong> message or throw an error message.<\/p>\n<h3>Step 13: Creating post request for add User<\/h3>\n<p>To create a post request, we need to require <strong>userValidation<\/strong> middleware and <strong>addUser<\/strong> function.<br \/>\n<strong>userRoute.js<\/strong><\/p>\n<pre>const userValidation = require(\"..\/controllers\/user\/user.validator\");\r\n\r\nconst { addUser } = require(\"..\/controllers\/user\/user.controller\");\r\n\r\nrouter.post(\"\/addUser\", userValidation, addUser);\r\n<\/pre>\n<h3>Testing AddUser API in Postman :<\/h3>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/qxZhjwT4IYw\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h3>Step 14: Fetching Users from Database <\/h3>\n<p><strong>user.controller.js<\/strong><\/p>\n<pre>const getUsers = async (req, res, next) => {\r\n\ttry {\r\n\t\tconst allUsers = await User.find();\r\n\t\tif (allUsers) {\r\n\t\t\tres.status(201);\r\n\t\t\treturn res.json(\r\n\t\t\t\terrorFunction(false, \"Sending all users\", allUsers)\r\n\t\t\t);\r\n\t\t} else {\r\n\t\t\tres.status(403);\r\n\t\t\treturn res.json(errorFunction(true, \"Error getting Users\"));\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tres.status(400);\r\n\t\treturn res.json(errorFunction(true, \"Error getting user\"));\r\n\t}\r\n};\r\n\r\nmodule.exports = { addUser, getUsers };\r\n<\/pre>\n<p>To fetch all the users from the database, we have to use the <strong>find()<\/strong> method of the <strong>User<\/strong> model. If users exist in the database, then it will display the users or else error messages.Once done export the <strong>getUsers()<\/strong> function.<\/p>\n<h3>Step 15: Creating get a request to fetch Users<\/h3>\n<p>To create get a request, we will use the <strong>getUsers<\/strong> function.<\/p>\n<p><strong>userRoute.js<\/strong><\/p>\n<pre>const { addUser, getUsers } = require(\"..\/controllers\/user\/user.controller\");\r\n\r\nrouter.get(\"\/getUsers\", getUsers);\r\n<\/pre>\n<h3>Testing getUsers API in Postman :<\/h3>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/I3lKmh7JAOU\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<p>Here\u2019s the source code of the demo application &#8211;  <strong><a href=\"https:\/\/github.com\/NisargChokshi45\/Task3NodeBlogs\/\" target=\"_blank\" rel=\"noopener\">Github Repository<\/a><\/strong><\/p>\n<p>After creating all the folders and files, the final project structure will look something like this-<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2021\/05\/image-3-min.png\" alt=\"Joi Validation\" width=\"1100\" height=\"584\" class=\"aligncenter size-full wp-image-21656\" srcset=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2021\/05\/image-3-min.png 1100w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2021\/05\/image-3-min-300x159.png 300w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2021\/05\/image-3-min-1024x544.png 1024w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2021\/05\/image-3-min-768x408.png 768w\" sizes=\"auto, (max-width: 1100px) 100vw, 1100px\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>So, this was all about implementing API Request Schema with express Joi Validation Node.js. I hope the tutorial of Node js joi validation example was helpful. If you wish to learn more about Joi NodeJS, please feel free to visit <a href=\"https:\/\/www.bacancytechnology.com\/tutorials\/nodejs\" target=\"_blank\" rel=\"noopener\">NodeJS Tutorials<\/a> without wasting a minute to start coding us!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Assume you\u2019re working on an endpoint that expects user data such as \u2013 username, age, address, pin code, state, and phone number. Consider a user entering numeric data for the username by mistake when you\u2019re expecting alphabetic data; a user entering an invalid pin code or birthdate for their respective fields when you\u2019re expecting the [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":18063,"comment_status":"open","ping_status":"open","sticky":false,"template":"blog-new-template.php","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_lmt_disableupdate":"no","_lmt_disable":"no","footnotes":""},"categories":[483],"tags":[],"coauthors":[1585],"class_list":["post-18057","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-node-js"],"acf":[],"modified_by":"Chandresh Patel","_links":{"self":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/18057","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/comments?post=18057"}],"version-history":[{"count":0,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/18057\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media\/18063"}],"wp:attachment":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media?parent=18057"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/categories?post=18057"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/tags?post=18057"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/coauthors?post=18057"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}