Template - API
WelcomePrerequisitesNodeJS
  • Welcome!
    • About me
  • Prerequisites
    • Installation and Database Setup
    • Installing Node.js on the Server
  • NodeJS
    • 🆓Getting Started with the Free Template
    • 🎗️Premium Template - REST API
      • Structure
      • Middlewares and Guards
      • Core Modules
        • Prisma with NestJS
        • Swagger with NestJS
      • Dynamic Module
        • Create or Import Module
  • Modules
    • 🎗️Websockets
    • 🎗️Mailer
    • 🎗️Upload
Powered by GitBook
On this page
  • Introduction to Swagger and NestJS
  • Setting Up Swagger in NestJS
  • Configuring Swagger in a Module
  • Documenting Controllers and DTOs
  1. NodeJS
  2. Premium Template - REST API
  3. Core Modules

Swagger with NestJS

We'll cover setting up Swagger, configuring it within your NestJS application, documenting controllers and DTOs, and ensuring your code adheres to SOLID principles for maintainability and scalability.


This is a tutorial that provides an overview of using the tool. There are many ways to code the logic and organize your code. It's up to you to design your API according to your specific needs. My role is to guide you and offer a solid foundation.

Introduction to Swagger and NestJS

Swagger is a powerful tool for designing, building, documenting, and consuming RESTful APIs. It provides a user-friendly interface to visualize and interact with your API’s resources without having any implementation logic in place.

NestJS is a progressive Node.js framework for building efficient and scalable server-side applications. It leverages TypeScript and incorporates concepts from object-oriented programming, functional programming, and functional reactive programming.

Integrating Swagger with NestJS allows developers to automatically generate interactive API documentation, enhancing the developer experience and facilitating easier API consumption.


Setting Up Swagger in NestJS

Step 1: Install Necessary Dependencies

First, ensure you have a NestJS project set up. If not, you can create one using the Nest CLI:

npm i -g @nestjs/cli
nest new my-nestjs-app

Navigate to your project directory:

cd my-nestjs-app

Install the @nestjs/swagger and swagger-ui-express packages:

npm install --save @nestjs/swagger swagger-ui-express

Step 2: Configure Swagger in the Application

Configure Swagger in your main.ts file to set up the Swagger module.

// src/main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Swagger configuration
  const config = new DocumentBuilder()
    .setTitle('My NestJS API')
    .setDescription('API documentation for my NestJS application')
    .setVersion('1.0')
    .addTag('users') // Example tag
    .addBearerAuth() // If using JWT Auth
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
  • DocumentBuilder: Helps in building the Swagger configuration.

  • SwaggerModule.createDocument: Generates the Swagger document based on the configuration and the modules in the application.

  • SwaggerModule.setup: Sets up the Swagger UI at the specified path (/api in this case).


Configuring Swagger in a Module

For better modularity and adherence to the Single Responsibility Principle, it's recommended to encapsulate Swagger configuration within its own module.

Step 1: Create a Swagger Configuration Module

Create a dedicated module for Swagger configuration.

mkdir src/config
touch src/config/swagger.config.ts src/config/swagger.module.ts

src/config/swagger.config.ts

// src/config/swagger.config.ts

import { DocumentBuilder } from '@nestjs/swagger';

export const swaggerConfig = new DocumentBuilder()
  .setTitle('My NestJS API')
  .setDescription('API documentation for my NestJS application')
  .setVersion('1.0')
  .addTag('users') // Add more tags as needed
  .addBearerAuth() // If using JWT Auth
  .build();

src/config/swagger.module.ts

// src/config/swagger.module.ts

import { Module, OnModuleInit } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { SwaggerModule } from '@nestjs/swagger';
import { swaggerConfig } from './swagger.config';
import { AppModule } from '../app.module';

@Module({})
export class SwaggerConfigModule implements OnModuleInit {
  async onModuleInit() {
    const app = await NestFactory.create(AppModule);
    const document = SwaggerModule.createDocument(app, swaggerConfig);
    SwaggerModule.setup('api', app, document);
  }
}

Note: Alternatively, you can keep Swagger configuration within main.ts for simplicity, especially for smaller projects. However, separating concerns as shown enhances maintainability in larger applications.

Update AppModule to Include SwaggerConfigModule

// src/app.module.ts

import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
import { SwaggerConfigModule } from './config/swagger.module';

@Module({
  imports: [UsersModule, SwaggerConfigModule],
})
export class AppModule {}

Documenting Controllers and DTOs

Proper documentation of your controllers and DTOs (Data Transfer Objects) ensures that the generated Swagger documentation is comprehensive and useful.

Step 1: Using Swagger Decorators in Controllers

NestJS provides decorators to annotate your controllers and their methods for Swagger.

Example: Users Controller

// src/users/users.controller.ts

import { Controller, Get, Post, Body, Param, HttpCode, HttpStatus } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody, ApiBearerAuth } from '@nestjs/swagger';
import { User } from './entities/user.entity';

@ApiTags('users')
@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  @ApiOperation({ summary: 'Create user' })
  @ApiResponse({ status: HttpStatus.CREATED, description: 'The user has been successfully created.', type: User })
  @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Invalid input.' })
  @ApiBody({ type: CreateUserDto })
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  @ApiOperation({ summary: 'Get all users' })
  @ApiResponse({ status: HttpStatus.OK, description: 'List of users.', type: [User] })
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  @ApiOperation({ summary: 'Get user by ID' })
  @ApiParam({ name: 'id', type: Number, description: 'User ID' })
  @ApiResponse({ status: HttpStatus.OK, description: 'The user.', type: User })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'User not found.' })
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }
}

Explanation of Decorators:

  • @ApiTags: Groups related endpoints under a common tag.

  • @ApiOperation: Describes the operation of the endpoint.

  • @ApiResponse: Specifies the expected responses, including status codes and descriptions.

  • @ApiParam: Documents path parameters.

  • @ApiBody: Describes the expected request body.

Step 2: Documenting Data Transfer Objects (DTOs)

Use decorators to define and document your DTOs, which represent the data structures for requests and responses.

Example: CreateUserDto

// src/users/dto/create-user.dto.ts

import { IsString, IsEmail, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class CreateUserDto {
  @ApiProperty({
    description: 'The name of the user',
    example: 'John Doe',
  })
  @IsString()
  @IsNotEmpty()
  name: string;

  @ApiProperty({
    description: 'The email of the user',
    example: 'john.doe@example.com',
  })
  @IsEmail()
  @IsNotEmpty()
  email: string;
}

Explanation of Decorators:

  • @ApiProperty: Describes a property within the DTO, providing metadata such as description and example values.

  • Class Validators (@IsString, @IsEmail, @IsNotEmpty): Ensure the data meets certain criteria, enhancing both validation and documentation.

Example: User Entity

// src/users/entities/user.entity.ts

import { ApiProperty } from '@nestjs/swagger';

export class User {
  @ApiProperty({
    description: 'The unique identifier of the user',
    example: 1,
  })
  id: number;

  @ApiProperty({
    description: 'The name of the user',
    example: 'John Doe',
  })
  name: string;

  @ApiProperty({
    description: 'The email of the user',
    example: 'john.doe@example.com',
  })
  email: string;

  @ApiProperty({
    description: 'The date the user was created',
    example: '2023-01-01T00:00:00Z',
  })
  createdAt: Date;

  @ApiProperty({
    description: 'The date the user was last updated',
    example: '2023-01-02T00:00:00Z',
  })
  updatedAt: Date;
}
PreviousPrisma with NestJSNextDynamic Module

Last updated 8 months ago

🎗️