In NestJS, when working with array-type data within the @Query object, several approaches can be employed. The choice depends on how the client sends query parameters and how you process them on the server side.
Here are some specific methods and examples:
Method 1: Using Comma-Separated Values
The client can send an array by providing comma-separated values, for example: ?ids=1,2,3. On the server side, you can use the @Query decorator to receive this string and manually convert it to an array.
typescriptimport { Controller, Get, Query } from '@nestjs/common'; @Controller('items') export class ItemsController { @Get() findAll(@Query('ids') ids: string): string[] { const idsArray = ids.split(',').map(id => parseInt(id, 10)); return idsArray; // [1, 2, 3] } }
Method 2: Using Array Format Directly
The client can directly send array format, for example: ?ids[]=1&ids[]=2&ids[]=3. NestJS automatically converts these values to an array.
typescriptimport { Controller, Get, Query } from '@nestjs/common'; @Controller('items') export class ItemsController { @Get() findAll(@Query('ids') ids: number[]): number[] { return ids; // [1, 2, 3] } }
Method 3: Using Custom Pipes
For more complex conversions or validations, you can create custom pipes to handle query parameters.
typescriptimport { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common'; @Injectable() export class ParseIntArrayPipe implements PipeTransform { transform(value: string, metadata: ArgumentMetadata): number[] { return value.split(',').map(val => parseInt(val, 10)); } } @Controller('items') export class ItemsController { @Get() findAll(@Query('ids', ParseIntArrayPipe) ids: number[]): number[] { return ids; // [1, 2, 3] } }
Method 4: Using Class Validators
To enforce stricter data handling with classes and validators, you can use class validators to define and validate input data.
typescriptimport { Type } from 'class-transformer'; import { IsArray, IsNumber, ValidateNested } from 'class-validator'; class IdsDto { @IsArray() @IsNumber({}, { each: true }) @Type(() => Number) ids: number[]; } @Controller('items') export class ItemsController { @Get() findAll(@Query() query: IdsDto): number[] { return query.ids; // [1, 2, 3] } }
These methods can be selected based on your specific requirements. Each approach offers distinct advantages; for instance, Methods 1 and 3 enable simple conversions and validations without additional dependencies, while Method 4 provides robust type checking and data validation.