Is there any JS smart json schema validator, like Joi maybe, but with dynamic custom errors?

I want to easily validate user's input.

When I ask the first name of the user (for example), it can take tons of lines of code in order to really make it good validated.

I want something that I can use in front end and either in back end - without changing the validation structure.

I need the ability to throw custom detailed errors, something like this:

let schema = Joi.object.keys({
  first_name: Joi.string("Required to be a string")
  .noNumbers("Should not contain numbers")
  .minlenth(2, "At least 2 chars")
  .maxlength(10, "Maximum 10 chars")
  .required("Required field"),
  last_name: Joi.string("Required to be a string")
  .noNumbers("Should not contain numbers")
  .minlenth(2, "At least 2 chars")
  .maxlength(10, "Maximum 10 chars")
  .required("Required field"),
});

Unfortunately the above does not work - since Joi does not work like this.

Maybe is there a good JSON schema validator to easily and efficiently validate the user's input without wasting time - and yet keep it clear for the user?

1 answer

  • answered 2018-10-17 08:32 Grégory NEUT

    You can use JOI. In the following example I'm overriding the errors directly :

       return Joi.object()
          .keys({
            str: Joi.string()
              .min(2)
              .max(10)
              .required()
              .error(errors => errors.map((err) => {
                const customMessage = ({
                  'string.min': 'override min',
                  'string.max': 'override max',
                })[err.type];
    
                if (customMessage) err.message = customMessage;
    
                return err;
              })),
          });
    

    I recommand you to use a function, considering the errors messages are going to be the same for all request :

    function customErrors(errors) {
       return errors.map((err) => {
            const customMessage = ({
                 'string.min': 'override min',
                 'string.max': 'override max',
            })[err.type];
    
            if (customMessage) err.message = customMessage;
    
           return err;
       });
    }
    
    return Joi.object()
        .keys({
          str: Joi.string()
               .min(2)
               .max(10)
               .required()
               .error(customErrors),
          });
    

    EDIT :

    // This
    
    const customMessage = ({
      'string.min': 'override min',
      'string.max': 'override max',
    })[err.type];
    
    if (customMessage) err.message = customMessage;
    
    
    // Equals this
    
    let customMessage = false;
    
    if (err.type === 'string.min') customMessage = 'override min';
    if (err.type === 'string.max') customMessage = 'override max';
    
    if (customMessage) err.message = customMessage;
    
    
    // Equals this
    
    if (err.type === 'string.min') err.message = 'override min';
    if (err.type === 'string.max') err.message = 'override max';