[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I need to validate the body of a request, that is an array of createCatDto, but inside the ValidationPipe, the metatype comes out as Array but the createCatDto gets lost and cannot validate the type.
Passing the metatype externally so I can validate every entry of the array with the proper class.
@Patch()
editCats(@Body() editCatDto: EditCatDto[]) {
return this.cat.updateBatch(editCatDto);
}
Nest version: 5.0.1
For Tooling issues:
- Node version: 8.11.1
- Platform: Mac
That is impossible through reflection: https://github.com/nestjs/nest/issues/335#issuecomment-365617027. I'd suggest creating your own validation pipe that extends existing one.
It is ok that it does not work out of the box, but would it be possible to type hint an array of mydto somehow?
How can I make ValidationPipe to throw validation error when incoming body is array, but I'm waiting SomeKindDto?
Now it breaks my service if someone sends me an array in API.
Following the example of AuthGuard, I implemented an ArrayValidationPipe that could be useful to anyone trying to validate plain arrays in HTTP body. At the moment I am not sure how to make it work as a singleton, but I use a memoize function for that performance.
Code:
import { ArgumentMetadata, mixin, PipeTransform, Type, ValidationPipe } from '@nestjs/common';
import { memoize } from 'lodash';
export const ArrayValidationPipe: <T>(itemType: Type<T>) => Type<PipeTransform> = memoize(createArrayValidationPipe);
function createArrayValidationPipe<T>(itemType: Type<T>): Type<PipeTransform> {
class MixinArrayValidationPipe extends ValidationPipe implements PipeTransform {
transform(values: T[], metadata: ArgumentMetadata): Promise<any[]> {
if (!Array.isArray(values)) {
return values;
}
return Promise.all(values.map(value => super.transform(value, { ...metadata, metatype: itemType })));
}
}
return mixin(MixinArrayValidationPipe);
}
Usage:
@Body(ArrayValidationPipe(User)) users: User[]
Following the example of AuthGuard, I implemented an ArrayValidationPipe that could be useful to anyone trying to validate plain arrays in HTTP body. At the moment I am not sure how to make it work as a singleton, but I use a
memoizefunction for that performance.Code:
import { ArgumentMetadata, mixin, PipeTransform, Type, ValidationPipe } from '@nestjs/common'; import { memoize } from 'lodash'; export const ArrayValidationPipe: <T>(itemType: Type<T>) => Type<PipeTransform> = memoize(createArrayValidationPipe); function createArrayValidationPipe<T>(itemType: Type<T>): Type<PipeTransform> { class MixinArrayValidationPipe extends ValidationPipe implements PipeTransform { transform(values: T[], metadata: ArgumentMetadata): Promise<any[]> { if (!Array.isArray(values)) { return values; } return Promise.all(values.map(value => super.transform(value, { ...metadata, metatype: itemType }))); } } return mixin(MixinArrayValidationPipe); }Usage:
@Body(ArrayValidationPipe(User)) users: User[]
Best solution I have ever seen.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Following the example of AuthGuard, I implemented an ArrayValidationPipe that could be useful to anyone trying to validate plain arrays in HTTP body. At the moment I am not sure how to make it work as a singleton, but I use a
memoizefunction for that performance.Code:
Usage:
@Body(ArrayValidationPipe(User)) users: User[]