Say goodbye to long if-else validation blocks! With the Joi npm package, you can achieve clean and efficient validation in just 4 simple steps.
Before diving into the steps, let's see how validations can be written using if-else.
const validateCreateCareer = (req, res, next) => { const { title, description, teamType, location, skills, salary, jobLevel, postingDate, employmentType, experienceRequired, remote } = req.body; if (!title) { return res.status(400).json({ status: 'error', message: 'Title is required.' }); } if (!description) { return res.status(400).json({ status: 'error', message: 'Description is required.' }); } if (!teamType || !['Engineering', 'Marketing', 'Sales'].includes(teamType)) { // Example teamType values return res.status(400).json({ status: 'error', message: 'Invalid or missing teamType.' }); } if (!Array.isArray(location) || location.some((loc) => typeof loc !== 'string')) { return res.status(400).json({ status: 'error', message: 'Location must be an array of strings.' }); } if (!Array.isArray(skills) || skills.some((skill) => typeof skill !== 'string')) { return res.status(400).json({ status: 'error', message: 'Skills must be an array of strings.' }); } if (salary !== undefined && typeof salary !== 'number') { return res.status(400).json({ status: 'error', message: 'Salary must be a number.' }); } next(); // Proceed if all validations pass }; export default validateCreateCareer; Drawbacks of if-else Validation
π£ Verbosity: The code becomes lengthy and repetitive.
π£ Error-Prone: Higher risk of missing edge cases or typos.
π£ Maintenance: Harder to maintain or extend as requirements grow.
Now let's look at the JOYOUS way
π οΈ Step 1: Install the Joi Package
Run the following command to install Joi:
npm i joi π οΈ Step 2: Configure Joi Validation Middleware
Create a reusable validation middleware to streamline your validation process:
import Joi from 'joi'; import { Request, Response, NextFunction } from 'express'; const validate = (schema: Joi.ObjectSchema<object>) => { return (req: Request, res: Response, next: NextFunction) => { const { error } = schema.validate(req.body); const valid = error == null; if (valid) { next(); } else { const { details } = error; const message = details.map((i) => i.message).join(','); const newMessage = message.replace(/"/g, ''); res.status(422).json({ status: 'error', message: newMessage, }); } }; }; export { validate }; π οΈ Step 3: Create a Joi Validator File
Define your validation schemas in a dedicated file:
createCareerSchema: Joi.object().keys({ title: Joi.string().required(), description: Joi.string().required(), teamType: Joi.string().valid(...Object.values(TeamType)).required(), location: Joi.array().items(Joi.string()).required(), skills: Joi.array().items(Joi.string()).required(), salary: Joi.number(), jobLevel: Joi.string().valid("Junior", "Mid-Level", "Senior").required(), postingDate: Joi.date().iso().required(), employmentType: Joi.string().valid("Full-Time", "Part-Time", "Contract").required(), experienceRequired: Joi.number().integer().min(0).required(), remote: Joi.boolean().default(false), }), }; export default careersSchema; π οΈ Step 4: Use It in Your Routes
Integrate the validation middleware in your Express routes:
import { validate } from './middleware/validate'; import careersSchema from './validators/careersSchema'; import CareersController from './controllers/CareersController'; router.patch( "/careers/:id/update", validate(careersSchema.updateCareerSchema), CareersController.updateCareer ); router.post( "/careers", validate(careersSchema.createCareerSchema), CareersController.createCareer ); export default router; β
Test It Out!
Try making API requests with missing or invalid fields. The middleware will automatically handle errors and return a user-friendly response. π
With these 4 steps, your validation process becomes concise, efficient, and easy to maintain. Happy coding! π

Top comments (0)