简体   繁体   中英

NestJs: Validating array of objects using class-validator

I am trying to enforce a validation on each item of an array.

As per my understanding (please correct me if I am wrong), class-validator does not support direct validation of arrays. It requires us to create a wrapper class.

So, the following are the classes:

export class SequenceQuery {   
    @MinLength(10, {
        message: 'collection name is too short',
      })
    collection: string;
    identifier: string;
    count: number;
}
export class SequenceQueries{
    @ValidateNested({ each: true })
    queries:SequenceQuery[];
}

And the following is my controller:

  @Get("getSequence")
  async getSequence(@Body() query:SequenceQueries) {
    return await this.sequenceService.getNextSequenceNew(query)
  }

The following is the JSON that I am passing to the controller:

{"queries":  [
    {
        "collection": "A",
        "identifier": "abc",
        "count": 1
    },
    {
        "collection": "B",
        "identifier": "mno",
        "count": 5
    },
    {
        "collection": "C",
        "identifier": "xyz",
        "count": 25
    }
]}

But it doesn't seem to be working. It's not throwing any validation messages.

I got the solution to the problem.

I was supposed to change my wrapper class to:

export class SequenceQueries{
    @ValidateNested({ each: true })
    @Type(() => SequenceQuery) // added @Type
    queries:SequenceQuery[];
}

But I will leave the question open, just in case someone has an alternate solution as in not having to make a wrapper class.

class-validator does support array validation you have just to add what you already did in @ValidateNested( { each: true } ), you have only to add each to the collection element:

export class SequenceQuery {   
@MinLength(10, {
    each: true,
    message: 'collection name is too short',
  })
collection: string;
identifier: string;
count: number;

}

source : Validation Array

There is my complete solution/implementation in Nestjs

  1. First create my DTO Class
export class WebhookDto {
  @IsString()
  @IsEnum(WebHookType)
  type: string;

  @IsString()
  @IsUrl()
  url: string;

  @IsBoolean()
  active: boolean;
}

export class WebhookDtoArray {
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => WebhookDto)
  webhooks: WebhookDto[];
}
  1. Place my DTO Class in my Controller definition
  @MessagePattern('set_webhooks')
  async setWebhooks(
    @Payload('body') webhookDtoArray: WebhookDtoArray,
    @Payload() data,
  ): Promise<Store> {
    return this.storeManagementService.setWebhooks(
      data.userPayload.id,
      webhookDtoArray,
    );
  }
  1. An example in Postman of what the Body I should send
{
  "webhooks": [{
      "type": "InvoiceCreated",
      "url": "https://test.free.beeceptor.com",
      "active": true
    },
    {
      "type": "InvoiceSettled",
      "url": "https://test.free.beeceptor.com",
      "active": true
    },
    {
      "type": "InvoiceExpired",
      "url": "https://test.free.beeceptor.com",
      "active": true
    }
  ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM