[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
## Current behavior
PartialType helper function from @nestjs/swagger package doesn't apply @IsOptional validation decorator.
## Expected behavior
Every property of reference class must have metadata from @IsOptional validation decorator.
## Minimal reproduction of the problem with instructions
Minimal reproduction repository (created from nestjs/sample/11-swagger repo):
[https://github.com/ivashog/nest/tree/modify-swagger-sample/sample/11-swagger](https://github.com/ivashog/nest/tree/modify-swagger-sample/sample/11-swagger)
also available on gitpod:
[](https://gitpod.io/#snapshot/76b06f48-28b1-4097-a630-e1912185b7b0)
The fastest way to reproduce:
1. Open gitpod link above.
2. In terminal do commands:
cd sample/11-swagger/
npm install
npm run start:dev
3. Press "Open in Browser" button
4. Add "/api" to current URL to open swagger page
5. Try to execute PATCH cats/:id endpoint with default example options (to save your time I prepared them in advance)
The answer will contain validation errors for properties that optional...
## What is the motivation / use case for changing the behavior?
## Environment
Nest version: 7.2.0
For Tooling issues:
- Node version: 12.18.0
- Platform: Linux
Others:
- "@nestjs/swagger": "^4.5.10",
- "swagger-ui-express": "^4.1.4"
- IDE: WebStorm
I studied this problem in more detail and found that it only occurs when the @nestjs/swagger/plugin is using in nest-cli.json. If manually add @ApiProperty decorator to all properties of the parent DTO, all works correctly.
If you look at the source code, the problem is in using ModelPropertiesAccessor class for getting list of properties that been iterated for applying IsOptional metadata:
export function PartialType<T>(classRef: Type<T>): Type<Partial<T>> {
const fields = modelPropertiesAccessor.getModelProperties(classRef.prototype);
...
It uses Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY ..., but with @nestjs/swagger/plugin @ApiProperty metadata applying at compilation time, and this code always return empty array:
export class ModelPropertiesAccessor {
getModelProperties(prototype: Type<unknown>): string[] {
const properties =
Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY, prototype) ||
[];
...
I hope this helps you fix this problem.
Fixed in 4.5.11. Thanks for reporting! Let me know if you have any further issues
Great, thanks @kamilmysliwiec , now everything works as expected!
Most helpful comment
I studied this problem in more detail and found that it only occurs when the @nestjs/swagger/plugin is using in nest-cli.json. If manually add @ApiProperty decorator to all properties of the parent DTO, all works correctly.
If you look at the source code, the problem is in using
ModelPropertiesAccessorclass for getting list of properties that been iterated for applying IsOptional metadata:It uses
Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY ..., but with @nestjs/swagger/plugin @ApiProperty metadata applying at compilation time, and this code always return empty array:I hope this helps you fix this problem.