Back to blog
Apr 14, 2024
4 min read
Muhammad Waqar Ilyas

Advanced API Documentation with NestJS and Swagger: A Comprehensive Guide

Learn how to create, customize, secure, and access API documentation in NestJS using Swagger. This guide covers everything from setup to advanced customization techniques.

Photo by Sigmund on Unsplash

NestJS offers an efficient and scalable way to build robust APIs, and when combined with Swagger, it empowers developers to create clear, structured, and secure API documentation. Whether you’re building an internal tool or a public-facing API, well-documented endpoints enhance collaboration, usability, and future maintainability. In this guide, we will walk through how to effectively set up Swagger, customize your documentation, and secure access to it within a NestJS application.

Installation and Setup

To start using Swagger in your NestJS project, first, install the required package:

npm install --save @nestjs/swagger

Then, initialize Swagger in your main.ts file:

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

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

  const config = new DocumentBuilder()
    .setTitle("Your API Title")
    .setDescription("Your API description")
    .setVersion("1.0")
    .addTag("YourTag")
    .build();

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

  await app.listen(3000);
}
bootstrap();

Customizing Swagger UI

Tailor your Swagger UI to reflect your branding or user experience needs by utilizing the SwaggerCustomOptions. This allows you to inject custom styles, scripts, and even logos:

SwaggerModule.setup("api", app, document, {
  customCss: ".swagger-ui .topbar { display: none }",
  customJs: "custom.js",
  customfavIcon: "favicon.ico",
  customSiteTitle: "My API Documentation",
});

With these customizations, you can control the UI’s appearance and make the API documentation more user-friendly.

Documenting API Endpoints

The real strength of Swagger in NestJS comes from its ability to generate comprehensive API documentation from code annotations. The @nestjs/swagger decorators help you define metadata for controllers and methods:

Example: Documenting a Book Controller

import { Controller, Get, Post, Body, Param } from "@nestjs/common";
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBody,
  ApiParam,
} from "@nestjs/swagger";
import { CreateBookDto } from "./dto/create-book.dto";
import { Book } from "./entities/book.entity";

@ApiTags("books")
@Controller("books")
export class BooksController {
  @Post()
  @ApiOperation({ summary: "Create a new book" })
  @ApiResponse({
    status: 201,
    description: "The book has been successfully created.",
    type: Book,
  })
  @ApiBody({ type: CreateBookDto })
  async create(@Body() createBookDto: CreateBookDto) {
    return this.booksService.create(createBookDto);
  }

  @Get(":id")
  @ApiOperation({ summary: "Get a book by id" })
  @ApiResponse({ status: 200, description: "The book details.", type: Book })
  @ApiParam({ name: "id", description: "The ID of the book to retrieve" })
  async findOne(@Param("id") id: string) {
    return this.booksService.findOne(+id);
  }
}

These annotations help define the API structure, request parameters, response models, and other useful details.

Securing API Documentation

To prevent unauthorized access to your API documentation, you can implement various authentication strategies such as Basic Auth, JWT, or OAuth2. Here’s how to secure the Swagger UI with JWT authentication:

const config = new DocumentBuilder()
  .setTitle("API Documentation")
  .setDescription("Description")
  .setVersion("1.0")
  .addBearerAuth()
  .build();

By adding BearerAuth(), you ensure that access to the API documentation is restricted to authenticated users only.

Advanced API Documentation: Custom Models and Validation

You can further enhance the documentation by defining custom data transfer objects (DTOs) and annotating them with @ApiProperty for detailed request and response models.

Example: Defining a DTO

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

export class CreateBookDto {
  @ApiProperty({
    example: "The Great Gatsby",
    description: "The title of the book",
  })
  title: string;

  @ApiProperty({
    example: "F. Scott Fitzgerald",
    description: "The author of the book",
  })
  author: string;
}

These DTOs help generate detailed and user-friendly documentation, making your API more understandable.

Conclusion

By integrating Swagger into your NestJS project, you not only make your API more accessible to developers but also lay the groundwork for scalability and maintainability. Through customization, you can tailor the API documentation to meet your application’s needs, providing both clarity and security. Follow this guide to take full advantage of NestJS and Swagger for seamless, professional API documentation.


For more detailed insights, check out the original story on JavaScript in Plain English.