NestJS course Β· Module 11: Swagger and OpenAPI

Swagger UI Customization - Decorating the Forum of Annals

3 min read
In this lesson9

Just as the Forum Romanum was decorated with columns, statues, and frescoes, our Swagger UI can be customized visually and functionally. NestJS offers many options for personalizing the documentation interface.

SwaggerModule.setup() Options

The fourth parameter of the setup() method allows for advanced configuration:

1SwaggerModule.setup('api/docs', app, document, {
2  customSiteTitle: 'Chronicles of Imperium Romanum',
3  customCss: '.swagger-ui .topbar { background-color: #8B0000; }',
4  swaggerOptions: {
5    persistAuthorization: true,
6    docExpansion: 'none',
7    filter: true,
8    showRequestDuration: true,
9    tryItOutEnabled: true,
10  },
11});

customSiteTitle - Name of the Notice Board

Changes the page title in the browser:

1SwaggerModule.setup('api/docs', app, document, {
2  customSiteTitle: 'Imperium API - Documentation',
3});

customCss - Frescoes on the Walls

Allows you to add custom CSS styles to Swagger UI:

1SwaggerModule.setup('api/docs', app, document, {
2  customCss: `
3    .swagger-ui .topbar { background-color: #8B0000; }
4    .swagger-ui .topbar-wrapper img { content: url('/logo.png'); }
5    .swagger-ui .info .title { color: #8B0000; }
6    .swagger-ui .btn.execute { background-color: #8B0000; }
7  `,
8});

swaggerOptions - Forum Regulations

Options controlling the behavior of Swagger UI:

OptionDescriptionDefault
persistAuthorizationKeep JWT token after refreshfalse
docExpansionDefault section expansion'list'
filterShow search fieldfalse
showRequestDurationShow response timefalse
tryItOutEnabledTesting mode enabled by defaultfalse
defaultModelsExpandDepthModel expansion depth1
defaultModelExpandDepthModel field expansion depth1
1SwaggerModule.setup('api/docs', app, document, {
2  swaggerOptions: {
3    persistAuthorization: true,
4    docExpansion: 'none',
5    filter: true,
6    showRequestDuration: true,
7  },
8});

addBearerAuth - Authorization Configuration

Full JWT authentication configuration in Swagger:

1const config = new DocumentBuilder()
2  .setTitle('Imperium API')
3  .addBearerAuth(
4    {
5      type: 'http',
6      scheme: 'bearer',
7      bearerFormat: 'JWT',
8      name: 'JWT',
9      description: 'Enter JWT token',
10      in: 'header',
11    },
12    'JWT-auth',
13  )
14  .build();

After this configuration, an "Authorize" button will appear in Swagger UI where the user can enter their JWT token.

operationIdFactory - Operation Names

Every operation in OpenAPI has a unique operationId. You can control how they are generated:

1const document = SwaggerModule.createDocument(app, config, {
2  operationIdFactory: (controllerKey: string, methodKey: string) =>
3    methodKey,
4});

By default, NestJS generates operationId in the format ControllerName_methodName. The above setting will use only the method name.

createDocument Options

The createDocument() method accepts additional options:

1const document = SwaggerModule.createDocument(app, config, {
2  // Include only selected modules
3  include: [LegionModule, ProvinceModule],
4
5  // Schema nesting depth
6  deepScanRoutes: true,
7
8  // Custom operationId generator
9  operationIdFactory: (controllerKey, methodKey) => methodKey,
10
11  // Additional models to include
12  extraModels: [ErrorResponseDto, PaginatedResponseDto],
13});

Securing the Documentation

In a production environment, it is worth securing access to Swagger UI:

1import * as basicAuth from 'express-basic-auth';
2
3// Before SwaggerModule.setup()
4app.use(
5  '/api/docs',
6  basicAuth({
7    challenge: true,
8    users: { admin: 'imperiumSecret123' },
9  }),
10);
11
12SwaggerModule.setup('api/docs', app, document);

Practical Exercise

Configure advanced Swagger UI options for the Imperium project:

Code for this lesson: src/main.ts
1// Swagger UI customization
2import { NestFactory } from '@nestjs/core';
3import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
4
5async function bootstrap() {
6  // const app = await NestFactory.create(AppModule);
7
8  const config = new DocumentBuilder()
9    .setTitle('Imperium Romanum API')
10    .setDescription('Imperium API Chronicles')
11    .setVersion('1.0')
12    // TODO: Add addBearerAuth with a full configuration:
13    // type: 'http', scheme: 'bearer', bearerFormat: 'JWT'
14    .build();
15
16  // const document = SwaggerModule.createDocument(app, config);
17
18  // TODO: Configure SwaggerModule.setup with options:
19  // customSiteTitle: 'Imperium API Chronicles'
20  // swaggerOptions:
21  //   persistAuthorization: true
22  //   docExpansion: 'none'
23  //   filter: true
24  //   showRequestDuration: true
25
26  // SwaggerModule.setup('api/docs', app, document, {
27  //   // TODO: Add customSiteTitle
28  //   // TODO: Add swaggerOptions
29  // });
30
31  console.log("Swagger UI: http://localhost:3000/api/docs");
32}
33
34bootstrap();
35
36console.log("=== Customization options ===");
37console.log("customSiteTitle - page title");
38console.log("customCss - custom CSS styles");
39console.log("swaggerOptions.persistAuthorization - keep the token");
40console.log("swaggerOptions.docExpansion - section expansion");
41console.log("swaggerOptions.filter - search field");
42console.log("swaggerOptions.showRequestDuration - response time");
43

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. What does the persistAuthorization option do in swaggerOptions?

  2. 2. What does the customSiteTitle option change in the SwaggerModule.setup() 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 SwaggerModule.setup options with customSiteTitle and swaggerOptions

  • Horizontal ordering

    Arrange the elements of the addBearerAuth configuration in the correct order:

  • Code editor

    Add full Swagger documentation (tags, operation, params, responses, auth) to the gladiator controller

Useful articles