Reputation: 171
I am trying to use swagger within my NestJS application and I am not able to define a custom class to be used for the additionalProperties typing.
I have a custom class:
@ApiExtraModels(Entity)
export class Entity {
@ApiProperty({description:"Map of the entities"}) entityID: string;
}
After this, I checked that the schema path(which should be defined by using the ApiExtraModels decorator) is defined - the console log...
console.log("getSchemaPath", getSchemaPath('Entity'));
...indeed has the output of:
getSchemaPath #/components/schemas/Entity
After this code, I tried to use this schema as a type for additional properties as such:
export class EntityLevel {
@ApiProperty({description:"Generic name of the entities in the current level"})
levelName: string;
@ApiProperty({
description:"Map object of the Entities - [GUID: string]: Entity",
type: 'object',
additionalProperties: {$ref: getSchemaPath('Entity')}
})
levelEntities: Map<string, Entity>;
}
But the output on the swagger for the given object is:
{
"levelName": "string",
"levelEntities": {}
}
My current workaround is to delete the @ApiExtraModels decorator and add a dummy property of type Entity to another class and then it works as it should(with a dummy property I do not want to have of course):
export class RandomClass {
id: String;
@ApiPropertyOptional({
description: "This is a dummy entity added as a workaround for not being able to include Entity type otherwise",
type: Entity
})
dummyEntity?: Entity;
}
Then the swagger for the object is as desired:
{
"levelName": "string",
"levelEntities": {
"additionalProp1": {
"entityID": "string"
},
"additionalProp2": {
"entityID": "string"
},
"additionalProp3": {
"entityID": "string"
}
}
}
What am I doing wrong when trying to define the ExtraModel with the @ApiExtraModels decorator?
Upvotes: 3
Views: 6023
Reputation: 145
as mentioned in issue #738, the ApiExtraModels
is to be used on top of a method, not on top of the model class.
Therefore your solution should be:
export class Entity {
@ApiProperty({description:"Map of the entities"}) entityID: string;
}
@ApiExtraModels(Entity)
export class EntityLevel {
@ApiProperty({description:"Generic name of the entities in the current level"})
levelName: string;
@ApiProperty({
description:"Map object of the Entities - [GUID: string]: Entity",
type: 'object',
additionalProperties: {$ref: getSchemaPath(Entity)}
})
levelEntities: Map<string, Entity>;
}
another way is by defining the extra models at main.ts
:
SwaggerModule.createDocument(app, config, {
extraModels: [.......]
});
In my case, i need the extra models to be put in { oneOf: [] }. This can be easily solved by listing the extra models inside ApiExtraModels annotation, such as:
@ApiExtraModels(EntityA, EntityB)
export class EntityLevel {
...
}
Upvotes: 2