preface

Nest works well with class-Validator, which allows us to use decorator-based validation, with some built-in annotations in the DTO layer for common validation of parameters.

However, when we are writing business code, the built-in annotations often can not meet our needs. At this time, we need to customize a annotation according to the requirements for the consistency of the code. This article will take you to implement a annotation, welcome you interested developers to read this article.

Scenario overview

The client passed in an invalid JSON string, which needs to be intercepted and converted into a JSON object for further verification. The string passed in by the client is as follows:

var config = '{"name":"aa","age":"21","title":" title test "}'
Copy the code

To do this, we need to truncate the var config = string and convert it to a JSON object, requiring the total number of attributes to be greater than 2. We can easily write code like this:

// Verify that the configuration string conforms to the specification
export function verifyConfig(draftConfig? :string
) :boolean | Record<string.any> {
  // Remove redundant characters
  if (draftConfig && draftConfig.length >= 12) {
    draftConfig = draftConfig.substring(12, draftConfig.length);
  }
  let draftData = {};
  try {
    if (typeof draftConfig === "string") {
      draftData = JSON.parse(draftConfig);
    }
    // The draft JSON field is insufficient
    if (Object.keys(draftData).length < 2) {
      return false; }}catch (e) {
    // The format of the draft configuration data is incorrect
    return false;
  }
  return draftData;
}

Copy the code

Implementation approach

This article continues the project created in the article “Building server-side Applications with NestJS” and expands on it.

After reading the custom-Validation-decorators section of the Class-Validator repository document, we have a rough idea of how it works, so let’s try it out.

Register decorator

First, we create a Decorators folder at the project root, where all the implementation files for the annotations will be placed. We then create the ConfigDecor. Ts file in its directory.

We use the registerDecorator method to register a decorator as follows:

  • IsConfig is the name of the annotation, which is the function type and takes an optional argument of type ValidationOptions
  • The decorator registration function has a Validator attribute that validates data, which is explained in more detail in the next section
// Configure validation annotations
export function IsConfig(validationOptions? : ValidationOptions) {
  return function (object: Record<string.any>, propertyName: string) :void {
    // Register a decorator
    registerDecorator({
      name: "IsConfig".target: object.constructor,
      options: validationOptions,
      propertyName: propertyName,
      validator: IsConfigConstraint
    });
  };
}

Copy the code

Data verification class

Decorator the validator attribute value is a decorated with @ ValidatorConstraint a class, this class must implement ValidatorConstraintInterface interface. The code looks like this:

  • The parameter validate takes is the value of the annotated field in the DTO. All we need is to validate it, using the validation function we wrote at the beginning of this articleverifyConfigMethods.
  • DefaultMessage is an error message returned to the client if the authentication fails
// Configure the validator
@ValidatorConstraint({ async: true })
export class IsConfigConstraint implements ValidatorConstraintInterface {
  validate(value: string) :Promise<boolean> | boolean {
    // Verify the draft configuration
    // If the verifier returns a Boolean value, the data format is incorrect
    return typeofverifyConfig(value) ! = ="boolean";
  }
  // Default error message when authentication fails
  defaultMessage(args: ValidationArguments): string {
    return `property ${args.property} data format error`; }}Copy the code

Use decorators

Finally, we just need to use it like a built-in decorator, as shown below:

export class AppDto {
  @MinLength(5)
  @IsString(a)publicid! :string;
  @IsString(a)publictitle! :string;
  @IsString(a)publicname! :string;
  @IsConfig(a)publicconfig! :string;
}

Copy the code

Finally, we started the project and tested it using Postman, as shown below:

  • We passed a nonconforming string that failed the decorator checksum and returned the default checksum we defined.

We are testing the correct data, as shown in the following figure, successfully called:

Tip: When we register the decorator, we provide an optional parameter that allows it to modify its public properties like a built-in annotation, such as message. We can customize the error message if the validation fails.

The sample code

For the complete code listed in this article, go to:

  • JsonDataVerifyUtilas.ts
  • ConfigDecor.ts
  • AppDto

Write in the last

At this point, the article is shared.

I’m an amazing programmer, a front-end developer.

If you are interested in me, please visit my personal website for further information.

  • If there are any errors in this article, please correct them in the comments section. If this article helped you, please like it and follow 😊
  • This article was first published in the magic programmer public number, without permission to prohibit reprinting 💌