NestJS course Β· Module 11: Swagger and OpenAPI

Installing and Configuring Swagger in NestJS

3 min read
In this lesson6

Before our chroniclers begin writing the annals, we must prepare the proper tools - parchment, ink, and imperial seals. In NestJS, this means installing the @nestjs/swagger package and configuring the Swagger module.

Package Installation

The first step is to install the official Swagger package for NestJS:

1npm install @nestjs/swagger

The @nestjs/swagger package contains everything we need: decorators, a configuration module, and Swagger UI integration.

DocumentBuilder - The Architect of Chronicles

DocumentBuilder is a class that allows you to build the API documentation configuration. It works like an architect who designs the structure of our annals:

1import { DocumentBuilder } from '@nestjs/swagger';
2
3const config = new DocumentBuilder()
4  .setTitle('Imperium Romanum API')
5  .setDescription('API documentation for managing the Roman Empire')
6  .setVersion('1.0')
7  .build();

DocumentBuilder Methods

MethodDescriptionExample
setTitle()Documentation name'Imperium API'
setDescription()Project description'API for managing legions'
setVersion()API version'1.0', '2.3.1'
addTag()Adds a tag (section)'Legiones'
addBearerAuth()Configures JWT authBearer options
setContact()Contact detailsName, URL, email
setLicense()API licenseName, URL
addServer()API serverURL, description
build()Finalizes configurationReturns OpenAPI object

SwaggerModule.setup() - Opening the Forum

After building the configuration, we need to "open the Forum" - that is, make the documentation available at a specific URL:

1import { NestFactory } from '@nestjs/core';
2import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
3import { AppModule } from './app.module';
4
5async function bootstrap() {
6  const app = await NestFactory.create(AppModule);
7
8  // 1. Build the documentation configuration
9  const config = new DocumentBuilder()
10    .setTitle('Imperium Romanum API')
11    .setDescription('API for managing provinces and legions of the Empire')
12    .setVersion('1.0')
13    .addTag('Legiones', 'Legion management')
14    .addTag('Provinciae', 'Province management')
15    .addTag('Tributum', 'Tax system')
16    .addBearerAuth()
17    .build();
18
19  // 2. Create the OpenAPI document
20  const document = SwaggerModule.createDocument(app, config);
21
22  // 3. Serve Swagger UI at the /api/docs path
23  SwaggerModule.setup('api/docs', app, document);
24
25  await app.listen(3000);
26}
27bootstrap();

After starting the application, Swagger UI will be available at http://localhost:3000/api/docs.

SwaggerModule.setup() Parameters

The setup() method accepts four arguments:

  1. path - the URL path for documentation (e.g., 'api/docs')
  2. app - the NestJS application instance
  3. document - the generated OpenAPI document
  4. options (optional) - additional configuration options
1SwaggerModule.setup('api/docs', app, document, {
2  customSiteTitle: 'Chronicles of the Imperium API',
3  customfavIcon: '/favicon.ico',
4  swaggerOptions: {
5    persistAuthorization: true,
6    docExpansion: 'none',
7    filter: true,
8  },
9});

Extended DocumentBuilder Configuration

Here is a full configuration example with all options:

1const config = new DocumentBuilder()
2  .setTitle('Imperium Romanum API')
3  .setDescription('Complete API documentation of the Roman Empire')
4  .setVersion('2.0')
5  .setContact('Caesar Augustus', 'https://imperium.rome', 'caesar@rome.gov')
6  .setLicense('MIT', 'https://opensource.org/licenses/MIT')
7  .addServer('http://localhost:3000', 'Development server')
8  .addServer('https://api.imperium.rome', 'Production server')
9  .addTag('Legiones', 'Legion management endpoints')
10  .addTag('Provinciae', 'Province management endpoints')
11  .addBearerAuth(
12    { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' },
13    'JWT-auth',
14  )
15  .build();

Practical Exercise

Configure Swagger in the main.ts file of the Imperium project:

Hold on to this rule, young chronicler: DocumentBuilder designs what the annals contain - the title, the version, the tags and the way a caller proves its identity - while SwaggerModule.setup() opens the forum where every legionary can read your API without ever asking you a single question.

Code for this lesson: src/main.ts
1// Swagger configuration in main.ts
2import { NestFactory } from '@nestjs/core';
3import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
4
5async function bootstrap() {
6  // const app = await NestFactory.create(AppModule);
7
8  // TODO: Create the DocumentBuilder configuration
9  // Use methods: setTitle, setDescription, setVersion, addTag, build
10  const config = new DocumentBuilder()
11    .setTitle('Imperium Romanum API')
12    // TODO: Add the API description
13    // TODO: Set version to '1.0'
14    // TODO: Add tag 'Legiones' with a description
15    // TODO: Add tag 'Provinciae' with a description
16    .build();
17
18  // TODO: Create the OpenAPI document
19  // const document = SwaggerModule.createDocument(app, config);
20
21  // TODO: Expose Swagger UI at the 'api/docs' path
22  // SwaggerModule.setup('api/docs', app, document);
23
24  // await app.listen(3000);
25  console.log("Swagger UI available at: http://localhost:3000/api/docs");
26}
27
28bootstrap();
29
30// Example of a full configuration:
31console.log("=== DocumentBuilder ===");
32console.log("setTitle() - documentation name");
33console.log("setDescription() - project description");
34console.log("setVersion() - API version");
35console.log("addTag() - section (group of endpoints)");
36console.log("addBearerAuth() - JWT configuration");
37console.log("build() - finalizes the configuration");
38console.log("");
39console.log("=== SwaggerModule ===");
40console.log("createDocument(app, config) - generates the OpenAPI spec");
41console.log("setup(path, app, document) - launches Swagger UI");
42

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. Which class in @nestjs/swagger is used to build the API documentation configuration?

  2. 2. What arguments does the SwaggerModule.setup() method accept in its minimal configuration?

These are 2 of 3 questions for this lesson. Solve the rest in the game.

Hands-on tasks in the game

  • Code editor

    Complete the Swagger configuration in main.ts by adding a description, version, and tags to DocumentBuilder

  • Horizontal ordering

    Arrange the DocumentBuilder method chain in the correct order:

  • Click in order

    Arrange the Swagger configuration steps in main.ts in the correct order:

  • Code editor

    Add @ApiTags('Centuriones') to the controller and @ApiOperation with a summary to the methods

Useful articles