Hello I am new to Nestjs
and trying to implement additionalProperties: false
on a DTO class that already has properties on it. I see that the additionalProperties
key can be added inside @ApiProperty({ schema: ... { additionalProperties : false} })
but I want to add it like this:
class SomeResponseDto {
@ApiResponseProperty()
text: string;
@ApiResponseProperty()
id: string;
// maybe a new Decorator like this?
@ApiAdditionalProperties(false)
}
...so that only text
and id
is allowed in the SomeResponseDto
. I want to avoid having to define every class as a schema object inside the controllers.
I should note that I'm using express-openapi-validator
with nestjs/swagger
, and do not want to use the class-validator
/class-transformer
plugins, so that I can validate responses as well as requests by using just nestjs/swagger
decorators.
I have also tried this:
@ApiResponse({
status: 200,
description: 'success',
schema: {
oneOf: [
{
$ref: getSchemaPath(SomeResponseDto),
// additionalProperties: false, <-- this gets ignored
},
],
// additionalProperties: false, <-- this throws OpenApi invalid response errors
},
Is there any easy way to add additionalProperties: false
on an existing DTO class?
Here is a workaround: Post this code inside the bootstrap()
method of the application
const schemas = document?.components?.schemas;
Object.keys(schemas).forEach((item) => {
if (schemas[item]['properties']?.allowAdditional) {
schemas[item]['additionalProperties'] = true;
} else {
schemas[item]['additionalProperties'] = false;
}
});
This code above will set additionalProperties
to false
by default.
If for some reason you have a DTO class that you want to allow additionalProperties: true
, then inside your DTO Class, add the following decorator and property:
export class SomeResponseDTO {
@ApiPropertyOptional()
allowAdditional?: boolean;
@ApiResponseProperty()
text: string;
@ApiResponseProperty()
id: string;
}
This is a simple solution for true
/false
case, but can be modified as needed to handle other use cases.
I hope this helps someone!