DEV Community

Cover image for Simplify Validation with Joi in Just 4 Steps πŸš€
Abayomi Ogunnusi
Abayomi Ogunnusi

Posted on

2

Simplify Validation with Joi in Just 4 Steps πŸš€

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;

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ 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 };
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ 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;
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ 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;
Enter fullscreen mode Exit fullscreen mode

βœ… Test It Out!
Try making API requests with missing or invalid fields. The middleware will automatically handle errors and return a user-friendly response. πŸŽ‰

Image description

With these 4 steps, your validation process becomes concise, efficient, and easy to maintain. Happy coding! πŸš€

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (0)

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

πŸ‘₯ Ideal for solo developers, teams, and cross-company projects

Learn more