itsdarja
itsdarja

Reputation: 171

NestJS Swagger - Definition of additionalProperties of a custom class not working with ApiExtraModels decorator

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

Answers (1)

nyoto arif
nyoto arif

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

Related Questions