# Swagger with NestJS

***

{% hint style="info" %}
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.
{% endhint %}

### 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:

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

Navigate to your project directory:

```bash
cd my-nestjs-app
```

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

```bash
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.

```typescript
// 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.

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

**`src/config/swagger.config.ts`**

```typescript
// 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`**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gruntsass.gitbook.io/template-api-nodejs/nodejs/premium-template-rest-api/core-modules/swagger-with-nestjs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
