nestjs-crud-microservice-validation
TypeScript icon, indicating that this package has built-in type declarations

2.1.6 • Public • Published

Summary

The following library is used to validate @NestJSX/CRUD request params, and data that is sending between micro-services using validation DTO or preset custom DTOs

Installation

npm install nestjs-crud-microservice-validation

Usage

Adding default validation to controller

In order to use the library, you need to add the @MicroserviceValidation(@validationDTO: Class) class decorator to a controller. The decorator takes as an argument validationDTO class, which determines all default validation rules for each request parameters, with list of method groups (create, read, update, delete) these rules are applied to.

Request group methods list:

- CrudRequestTypes.CREATE - createOne, createMany;
- CrudRequestTypes.UPDATE - updateOne, replaceOne;
- CrudRequestTypes.DELETE - deleteOne;
- CrudRequestTypes.READ   - getOne, getMany

To apply validation rules to specific request type methods you should add this request type to validation decorator groups option array.

@IsBoolean({groups: [CrudRequestTypes.UPDATE, CrudRequestTypes.READ})

All other method names are considered as custom methods and require custom validation dto added.

Decorator usage:

import { MicroserviceValidation, CrudRequestTypes } from 'nestjs-crud-microservice-validation';
import { MessagePattern } from '@nestjs/microservices';
import { CrudRequest } from '@nestjsx/crud';
import { IsString } from 'class-validator';


//Validation dto
class ExampleDtoClass {
    //Validation is added for both create and update request types.
    @IsString({groups: [CrudRequestTypes.CREATE, CrudRequestTypes.UPDATE]})
    //Field is optional only for update request types.
    @IsOptional({groups: [CrudRequestTypes.UPDATE]})
    stringField?: string;
}

//Adding validation to controller methods using dto created above
@MicroserviceValidation(ExampleDtoClass)
class ExapmleController {
    //Because method is default @nestjsx/crud method and no custom validation is added
    //"req" and "dto" properties of data argument will be validated 
    //based on rules in DTO added to @MicroserviceValidation decorator
    @MessagePattern({exampleMicroservice: {example: 'createOne'}})
    createOne(data: {req: CrudRequest; dto: ExampleDtoClass}){
        //Some creating logic
    }
}

_______________________________

Adding custom validation to method

In case if you want to add custom dto to specific method you have to add @RmqTrasportDtoType to method argument. Decorator should get custom Dto class as an argument.

import { MicroserviceValidation, RmqTransportDtoType } from 'nestjs-crud-microservice-validation';

@MicroserviceValidation(BaseDto)
class ExampleController {
    @MessagePattern({exampleMicroservice: {example: 'createOne'}})
    //Because custom validation is added
    //"req" and "dto" properties of data argument will be validated 
    //based on rules in CustomDto. Validation rules from BaseDto are ignored.
    createOne(@RmqTransportDtoType(CustomDto) data: { req: CrudRequest; dto: CustomDto }) {
        //Some creating logic
    }
}

Important:

  • Custom dto class should contain Dto part in class name. CustonDto, GetUserDto, CreateUserDto ... etc.
  • @RmqTransportDtoType decorator is required for all custom methods added to controller.
  • In case of custom method validation, crud request method groups are not required.

_______________________________

Nested validation

In case if you want to manage relation between your dto classes you should add @RelatedDto decorator to property with nested dto validation.

@RelatedDto decorator allows managing nested relations for property (it's added to) from current dto or parent dto in case if your dto is nested one.

To specify nested relations for property you should add nested property names as strings to nestedRelations options. All nested levels have to be separated by dot notation.

import { ValidateNested } from 'class-validator';
import { RelatedDto, CrudRequestTypes } from 'nestjs-crud-microservice-validation';

class SecondNestedDto {
    @RelatedDto()
    @ValidateNested({
        context: ThirdNestedDto,
        groups: [CrudRequestTypes.CREATE, CrudRequestTypes.UPDATE]
    })
    thirdNested: ThirdNestedDto;
}

class FirstNestedDto {
    //Decorator should be added for each property you want to manage nested relation for
    @RelatedDto()
    @ValidateNested({
        context: SecondNestedDto,
        groups: [CrudRequestTypes.CREATE, CrudRequestTypes.UPDATE]
    })
    secondNested: SecondNestedDto;
}

class MainDto {
    //Allows to also include "secondNested" property of FirstNestedDto 
    //and "thirdNested" property of SecondNestedDto to validation process
    @RelatedDto({nestedRelations: ['secondNested', 'secondNested.thirdNested']})
    @ValidateNested({
        context: FirstNestedDto,
        groups: [CrudRequestTypes.CREATE, CrudRequestTypes.UPDATE]
    })
    firstNested?: FirstNestedDto;
}

Validation process checks only nestedRelations option of main Dto and ignores values of nestedRelations option for all nested Dto.

import { ValidateNested } from 'class-validator';
import { RelatedDto, CrudRequestTypes, MicroserviceValidation } from 'nestjs-crud-microservice-validation';

class SecondNestedDto {
    @RelatedDto()
    @ValidateNested({context: ThirdNestedDto})
    thirdNested: ThirdNestedDto;

    @RelatedDto()
    @ValidateNested({context: ForthNestedDto})
    forthNested: ForthNestedDto;
}

class FirstNestedDto {
    @RelatedDto({nestedRelations: ['forthNested']})
    @ValidateNested({context: SecondNestedDto})
    secondNested: SecondNestedDto;
}

class MainDto {
    @RelatedDto({nestedRelations: ['secondNested', 'secondNested.thirdNested']})
    @ValidateNested({
        context: FirstNestedDto,
        groups: [CrudRequestTypes.CREATE, CrudRequestTypes.UPDATE]
    })
    firstNested?: FirstNestedDto;
}

//Validates thirdNested field of SecondDto    
@MicroserviceValidation(MainDto)
class ExampleClass {
  //Some methods   
}

//Validates forthNested field of SecondDto  
@MicroserviceValidation(FirstNestedDto)
class AnotherExampleClass {
  //Some methods    
}

In example above base validation for ExampleClass will ignore {nestedRelations: ['forthNested']} option added to secondNested property of FirstNestedDto because in this case its applied for nested dto and main dto is MainDo class, so validation will check only it's nestedRelations option of @RelatedDto.

Validation for AnotherExampleClass will validate forthNested property of SecondNestedDto because in this main dto is FirstNestedDto and it's nestedRelations options of @RelatedDto are considered as main options for all nested relations.

_______________________________

Request validation

Request validation works with all queries from @NestJSX/CRUD request params, but there are few cases you should know about.

"isnull" and "notnull" operators:

isnull and notnull operators might be applied only to fields that are allowed to have null value.

import { IsString, IsOptional } from 'class-validator';
import { CrudRequestTypes } from 'nestjs-crud-microservice-validation';

class RequestValidationDto {
    //Field is not allowed for `isnull` and `notnull` request query operators and will throw validation error
    @IsString({groups: [CrudRequestTypes.READ]})
    requiredField: string;

    //Field is allowed for `isnull` and `notnull` request query operators
    @IsString({groups: [CrudRequestTypes.READ]})
    @IsOptional({groups: [CrudRequestTypes.READ]})
    optionalField?: string;
}

"ValidateIf" decorator

Request validation validate each dto property separately, so it is not work correct for properties with @ValidateIf decorator that refers to other dto properties in argument function.

import { IsString, IsOptional } from 'class-validator';

class RequestValidationDto {
    //This validation is not work correct for request queries validation
    //because it refers to `secondField` dto property
    @ValidateIf(o => o.secondField !== 'test', {groups: [CrudRequestTypes.READ]})
    @IsString({groups: [CrudRequestTypes.READ]})
    firstField?: string;

    //This validations works correct for request queries validation
    //because it doesnt reffers to other dto properties
    @ValidateIf(o => o.secondField !== 'test', {groups: [CrudRequestTypes.READ]})
    @IsString({groups: [CrudRequestTypes.READ]})
    secondField?: string;
}

Joins

Join query is not allowed for properties without@ValidateNested decorator.

Working with nested fields

All nested levels have to be separated by dot notation. Example: {fields: ['user', 'user.name']}

_______________________________

Enabling validation only for nested dto properties (for CRUD methods only)

The validation decorator @ValidateIfRelatedOnly can be used to apply the validators on a property when its parent dto is nested, and remove validation rules in case if parent dto is base dto.

@ValidateIfRelatedOnly is implemented by using ValidateIf logic, so using both @ValidateIfRelatedOnly and @ValidateIf decorators on the same property is not recommended.

In example bellow validation of ParentDto for both CREATE and READ CRUD method groups will require both someField and someOtherField properties to exists in FirstNestedDto payload.

If you validate FirstNestedDto directly, someField is required only for READ method group and should not exist in CREATE group methods, because @ValidateIfRelatedOnly decorator is applied to CREATE group.

import { IsString, IsOptional } from 'class-validator';
import { RelatedDto, ValidateIfRelatedOnly, CrudRequestTypes } from 'nestjs-crud-microservice-validation';

class FirstNestedDto {
    @ValidateIfRelatedOnly({groups: [CrudRequestTypes.CREATE]})
    @IsString({groups: [CrudRequestTypes.CREATE, CrudRequestTypes.READ]})
    someField: string;

    @IsString({groups: [CrudRequestTypes.CREATE, CrudRequestTypes.READ]})
    someOtherField: string;
}

class ParentDto {
    @RelatedDto()
    @ValidateNested({
        context: FirstNestedDto, 
        groups: [CrudRequestTypes.CREATE, CrudRequestTypes.READ]
    })
    firstNested: FirstNestedDto;
}

Readme

Keywords

none

Package Sidebar

Install

npm i nestjs-crud-microservice-validation

Weekly Downloads

110

Version

2.1.6

License

ISC

Unpacked Size

342 kB

Total Files

99

Last publish

Collaborators

  • devaskuma