Swagger

Introduction

  • To set the plugin, so that nestjs/swagger will add @ApiPropertyto the dto class automatically

nest-cli.json
{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true,
    "plugins": ["@nestjs/swagger/plugin"]
  }
}
  • Create the setting

swagger-document.ts
export const initializeSwaggerDoc = (app: INestApplication) => {
  const contextPath = process.env.CONTEXT_PATH || 'v1';
  app.setGlobalPrefix(contextPath);
  const config = new DocumentBuilder()
    .setTitle('Test API')
    .setDescription('Draft version')
    .setVersion('1.0')
    //   .addServer(process.env.BACKEND_ENV)
    .setBasePath(contextPath)
    .build();

  const options: SwaggerDocumentOptions = {
    include: [AppModule],
    deepScanRoutes: true,
    operationIdFactory: (controllerKey: string, methodKey: string) => methodKey,
  };

  const documentFactory = SwaggerModule.createDocument(app, config, options);

  // The ui will be generated on /v1/open-api
  // The open api spec will be generated on /v1/open-api-json
  SwaggerModule.setup(`${contextPath}/open-api`, app, documentFactory, {
    swaggerOptions: {
      tagsSorter: 'alpha',
      operationsSorter: 'alpha',
    },
  });
};
main.ts
initializeSwaggerDoc(app);
  • The SwaggerModule searches for all @Body(), @Query(), and @Param() decorators in route handlers to generate the API document

  • In order to make the class properties visible to the SwaggerModule, we have to either annotate them with the @ApiProperty() decorator or use the CLI plugin (read more in the Plugin section) which will do it automatically

Api Property

  • To override the attributes of object, it can be declared through decorator

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}

export class TestType {
  name: string;
  age: number;
  @ApiProperty({ enum: ['Admin', 'Moderator', 'User'], description: 'User Role' })
  role: UserRole;
}

Api Response

  • In order to declare the schema of api response, it is needed to declare via api extra models and api response decorators


 @ApiExtraModels(ContentPointEntity)
 @ApiResponse({
    status: 200,
    description: 'OK',
    content: {
      'application/json': {
        schema: {
          $ref: getSchemaPath(ContentPointEntity),
        },
      },
    },
  })
async createInsightCase(@Body() createInsightCaseDto: CreateInsightCaseDto) {
  return await this.insightService.createInsightCase(createInsightCaseDto);
}
  • In order to make code clearer , it can be grouped into single decorator

import { applyDecorators, Type } from '@nestjs/common';
import { PaginatedDto2 } from './insight.dto';
import { ApiExtraModels, ApiResponse, getSchemaPath, PartialType } from '@nestjs/swagger';
export const ApiPaginatedResponse = 
<TModel extends Type<any>>(model: TModel) => {
  return applyDecorators(
    ApiExtraModels(PaginatedDto2, model),
    ApiResponse({
      status: 200,
      description: 'OK',
      schema: {
        allOf: [
          { $ref: getSchemaPath(PartialType(PaginatedDto2)) },
          {
            properties: {
              results: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};

Last updated

Was this helpful?