How to add Swagger docs for APIs returning collections in NestJS

Table of contents

In this post, we will learn how to add Swagger documentation for APIs returning collections in NestJS. We will use @ApiProperty decorator to specify the type of the collection and its items.

Case 1: API returns a collection of objects

Let's say we have an API that returns a collection of objects, normalized by some ID. We can use @ApiProperty decorator to specify the type of the collection and its items.

The API response will look like this:

{
  "people": {
    "1": { "name": "John" },
    "2": { "name": "Doe" }
  }
}

First, let's create a simple API that returns a collection of objects. (Here and below imports are omitted for brevity)

export class PeopleController {
  @Get('case-1')
  @ApiResponse({
    type: People,
  })
  collectionOfObjects(): People {
    return {
      people: {
        1: { name: 'John' },
        2: { name: 'Doe' },
      }
    }
  }
}

We are describing the return type by next DTO class:

@Controller('people')
export class Person {
    @ApiProperty()
    name: string;
}

@ApiExtraModels(Person)
export class People {
    @ApiProperty({
        type: 'object',
        properties: { ['PERSON_ID']: { $ref: getSchemaPath(Person) } },
    })
    people: Record<string, Person>;
}

We described the People class with @ApiProperty decorator. We specified the type of the collection and its items. We also used @ApiExtraModels decorator to specify the extra models that are not directly referenced in the API.

The Swagger documentation for the API will look like this:

Swagger objects collections

Case 2: API returns a collection of arrays of strings

Let's say we have an API that returns a collection of arrays of strings.

The API response will look like this:

{
  "people": {
    "1": ["John", "Doe"],
    "2": ["Jane", "Doe"]
  }
}

First, let's create a simple API that returns a collection of arrays of strings.

@Controller('people')
export class CatsController {
  @Get('case-2')
  @ApiResponse({
    type: PeopleArray,
  })
  collectionOfArrays(): PeopleArray {
    return {
      people: {
        1: ['John', 'Doe'],
        2: ['Jane', 'Doe']
      }
    }
  }
}

We are describing the return type by next DTO class:

export class PeopleArray {
    @ApiProperty({
        type: 'object',
        properties: {
            ['PEOPLE_GROUP_ID']: {
                type: 'array',
                items: { type: 'string' },
            },
        },
    })
    people: Record<string, string[]>;
}

The Swagger documentation for the API will look like this:

Swagger objects collections