CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nestjs--swagger

OpenAPI (Swagger) module for Nest framework enabling automatic API documentation generation from TypeScript decorators

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

swagger-module.mddocs/

SwaggerModule

The SwaggerModule class is the main integration point between NestJS applications and Swagger UI. It provides static methods for creating OpenAPI documents from your NestJS application metadata and setting up interactive Swagger UI documentation interfaces.

Class Overview

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

class SwaggerModule {
  static createDocument(
    app: INestApplication,
    config: Omit<OpenAPIObject, 'paths'>,
    options?: SwaggerDocumentOptions
  ): OpenAPIObject;
  
  static setup(
    path: string,
    app: INestApplication,
    documentOrFactory: OpenAPIObject | (() => OpenAPIObject),
    options?: SwaggerCustomOptions
  ): void;
  
  static loadPluginMetadata(
    metadataFn: () => Promise<Record<string, any>>
  ): Promise<void>;
}

Document Creation

createDocument { .api }

static createDocument(
  app: INestApplication,
  config: Omit<OpenAPIObject, 'paths'>,
  options?: SwaggerDocumentOptions
): OpenAPIObject

Creates a complete OpenAPI document by scanning the NestJS application for controllers, decorators, and metadata, then combining it with the provided configuration.

Parameters:

  • app: The NestJS application instance
  • config: OpenAPI document configuration (typically from DocumentBuilder)
  • options: Optional document generation options

Type Definitions:

interface SwaggerDocumentOptions {
  include?: Function[];
  extraModels?: Function[];
  ignoreGlobalPrefix?: boolean;
  deepScanRoutes?: boolean;
  operationIdFactory?: OperationIdFactory;
  linkNameFactory?: (controllerKey: string, methodKey: string, fieldKey: string) => string;
  autoTagControllers?: boolean;
}

type OperationIdFactory = (
  controllerKey: string,
  methodKey: string,
  version?: string
) => string;

Basic Usage:

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

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

  const config = new DocumentBuilder()
    .setTitle('My API')
    .setDescription('API description')
    .setVersion('1.0')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  
  // Document now contains all paths, schemas, and operations
  console.log(document.paths); // All endpoint definitions
  console.log(document.components); // All schema definitions
}

Advanced Usage with Options:

import { ProductModule, UserModule } from './modules';
import { BaseDto, ErrorDto } from './common/dto';

const document = SwaggerModule.createDocument(app, config, {
  // Only include specific modules
  include: [ProductModule, UserModule],
  
  // Add extra models that aren't automatically discovered
  extraModels: [BaseDto, ErrorDto],
  
  // Scan imported modules deeply
  deepScanRoutes: true,
  
  // Custom operation ID generation
  operationIdFactory: (controllerKey, methodKey, version) => {
    return `${controllerKey.toLowerCase()}_${methodKey}_v${version || '1'}`;
  },
  
  // Custom link name generation for OpenAPI links
  linkNameFactory: (controllerKey, methodKey, fieldKey) => {
    return `link_${controllerKey}_${methodKey}_${fieldKey}`;
  },
  
  // Disable automatic tag generation from controller names
  autoTagControllers: false,
  
  // Ignore global prefix for this documentation
  ignoreGlobalPrefix: true
});

Swagger UI Setup

setup { .api }

static setup(
  path: string,
  app: INestApplication,
  documentOrFactory: OpenAPIObject | (() => OpenAPIObject),
  options?: SwaggerCustomOptions
): void

Sets up Swagger UI at the specified path, serving both the interactive documentation interface and the raw OpenAPI specification in JSON/YAML formats.

Parameters:

  • path: URL path where Swagger UI will be served
  • app: The NestJS application instance
  • documentOrFactory: OpenAPI document or factory function to generate it
  • options: Extensive customization options for Swagger UI

Type Definitions:

interface SwaggerCustomOptions {
  useGlobalPrefix?: boolean;
  ui?: boolean;
  raw?: boolean | Array<'json' | 'yaml'>;
  swaggerUrl?: string;
  jsonDocumentUrl?: string;
  yamlDocumentUrl?: string;
  patchDocumentOnRequest?: <TRequest = any, TResponse = any>(
    req: TRequest,
    res: TResponse,
    document: OpenAPIObject
  ) => OpenAPIObject;
  explorer?: boolean;
  swaggerOptions?: SwaggerUiOptions;
  customCss?: string;
  customCssUrl?: string | string[];
  customJs?: string | string[];
  customJsStr?: string | string[];
  customfavIcon?: string;
  customSiteTitle?: string;
  customSwaggerUiPath?: string;
}

Basic Setup:

const config = new DocumentBuilder()
  .setTitle('E-Commerce API')
  .setVersion('1.0')
  .build();

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

// Serve Swagger UI at /api-docs
SwaggerModule.setup('api-docs', app, document);

// Now available at:
// http://localhost:3000/api-docs - Swagger UI interface
// http://localhost:3000/api-docs-json - JSON specification
// http://localhost:3000/api-docs-yaml - YAML specification

Advanced Customization:

SwaggerModule.setup('api-docs', app, document, {
  // Use global prefix if app.setGlobalPrefix() was called
  useGlobalPrefix: true,
  
  // Customize document URLs
  jsonDocumentUrl: '/api/v1/spec.json',
  yamlDocumentUrl: '/api/v1/spec.yaml',
  
  // Enable OpenAPI definition selector in UI
  explorer: true,
  
  // Swagger UI customization
  swaggerOptions: {
    // Keep authorization when page refreshes
    persistAuthorization: true,
    // Display request duration
    displayRequestDuration: true,
    // Expand operations by default
    docExpansion: 'list',
    // Try it out enabled by default
    tryItOutEnabled: true,
    // Show/hide request examples
    requestInterceptor: (req) => {
      console.log('Request:', req);
      return req;
    }
  },
  
  // Custom styling
  customSiteTitle: 'E-Commerce API Documentation',
  customfavIcon: '/favicon.ico',
  customCss: `
    .topbar-wrapper { display: none; }
    .swagger-ui .info { margin: 20px 0; }
  `,
  customCssUrl: [
    'https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap'
  ],
  
  // Dynamic document patching per request
  patchDocumentOnRequest: (req, res, document) => {
    // Add user-specific info or filter content based on request
    const userRole = req.headers['x-user-role'];
    
    if (userRole !== 'admin') {
      // Remove admin-only paths
      const filteredPaths = {};
      Object.keys(document.paths).forEach(path => {
        if (!path.includes('/admin/')) {
          filteredPaths[path] = document.paths[path];
        }
      });
      document.paths = filteredPaths;
    }
    
    return document;
  }
});

Document Factory Pattern:

// Use factory for dynamic document generation
SwaggerModule.setup('api-docs', app, () => {
  const config = new DocumentBuilder()
    .setTitle('Dynamic API')
    .setVersion(process.env.API_VERSION || '1.0')
    .setDescription(`Built at: ${new Date().toISOString()}`)
    .build();
    
  return SwaggerModule.createDocument(app, config);
}, {
  customSiteTitle: 'Dynamic API Documentation'
});

Selective Serving Options

UI and Raw Document Control

// Serve only Swagger UI (no raw JSON/YAML endpoints)
SwaggerModule.setup('docs', app, document, {
  ui: true,
  raw: false
});

// Serve only JSON specification (no UI or YAML)
SwaggerModule.setup('docs', app, document, {
  ui: false,
  raw: ['json']
});

// Serve UI and only YAML specification
SwaggerModule.setup('docs', app, document, {
  ui: true,
  raw: ['yaml']
});

// Disable everything (useful for conditional setup)
if (process.env.NODE_ENV !== 'production') {
  SwaggerModule.setup('docs', app, document, {
    ui: true,
    raw: true
  });
} else {
  SwaggerModule.setup('docs', app, document, {
    ui: false,
    raw: false
  });
}

Plugin Metadata Loading

loadPluginMetadata { .api }

static loadPluginMetadata(
  metadataFn: () => Promise<Record<string, any>>
): Promise<void>

Loads metadata from the Swagger TypeScript compiler plugin for enhanced automatic documentation generation.

Usage:

// In your main.ts, before creating the document
await SwaggerModule.loadPluginMetadata(() => 
  import('./swagger-plugin-metadata')
);

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

Complete Integration Examples

Production-Ready Setup

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  
  // Set global prefix
  app.setGlobalPrefix('api/v1');
  
  // Load plugin metadata for enhanced documentation
  if (process.env.NODE_ENV !== 'production') {
    try {
      await SwaggerModule.loadPluginMetadata(() => 
        import('./swagger-plugin-metadata')
      );
    } catch (error) {
      console.warn('Could not load Swagger plugin metadata:', error.message);
    }
  }

  // Create comprehensive document configuration
  const config = new DocumentBuilder()
    .setTitle('E-Commerce Platform API')
    .setDescription('Comprehensive e-commerce platform REST API')
    .setVersion('2.0.0')
    .setContact('API Team', 'https://example.com/contact', 'api@example.com')
    .setLicense('MIT', 'https://opensource.org/licenses/MIT')
    .addServer('https://api.example.com', 'Production')
    .addServer('https://staging-api.example.com', 'Staging')
    .addBearerAuth()
    .addApiKey({ type: 'apiKey', in: 'header', name: 'X-API-Key' })
    .addTag('Authentication', 'User authentication and authorization')
    .addTag('Products', 'Product catalog management')
    .addTag('Orders', 'Order processing and fulfillment')
    .build();

  // Generate document with advanced options
  const document = SwaggerModule.createDocument(app, config, {
    deepScanRoutes: true,
    autoTagControllers: true,
    operationIdFactory: (controllerKey, methodKey, version) => 
      `${controllerKey}_${methodKey}${version ? `_v${version}` : ''}`,
  });

  // Setup with extensive customization
  SwaggerModule.setup('docs', app, document, {
    useGlobalPrefix: true,
    explorer: true,
    swaggerOptions: {
      persistAuthorization: true,
      displayRequestDuration: true,
      filter: true,
      showExtensions: true,
      showCommonExtensions: true,
      docExpansion: 'list'
    },
    customSiteTitle: 'E-Commerce API - Interactive Documentation',
    customfavIcon: 'https://example.com/favicon.ico',
    customCss: `
      .swagger-ui .topbar { display: none; }
      .swagger-ui .info .title { color: #1f2937; }
    `,
    customCssUrl: 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600',
  });

  await app.listen(3000);
  
  console.log(`Application is running on: ${await app.getUrl()}`);
  console.log(`Swagger UI available at: ${await app.getUrl()}/api/v1/docs`);
}

bootstrap();

Multi-Version API Setup

async function setupMultiVersionDocs(app: INestApplication) {
  // V1 API Documentation
  const v1Config = new DocumentBuilder()
    .setTitle('API v1')
    .setVersion('1.0')
    .addBearerAuth()
    .build();
    
  const v1Document = SwaggerModule.createDocument(app, v1Config, {
    include: [V1Module],
    ignoreGlobalPrefix: true
  });
  
  SwaggerModule.setup('docs/v1', app, v1Document);

  // V2 API Documentation  
  const v2Config = new DocumentBuilder()
    .setTitle('API v2')
    .setVersion('2.0')
    .addBearerAuth()
    .addOAuth2()
    .build();
    
  const v2Document = SwaggerModule.createDocument(app, v2Config, {
    include: [V2Module],
    ignoreGlobalPrefix: true
  });
  
  SwaggerModule.setup('docs/v2', app, v2Document);

  // Combined documentation with version selector
  const combinedConfig = new DocumentBuilder()
    .setTitle('Multi-Version API')
    .setVersion('latest')
    .addBearerAuth()
    .build();
    
  const combinedDocument = SwaggerModule.createDocument(app, combinedConfig, {
    include: [V1Module, V2Module],
    deepScanRoutes: true
  });
  
  SwaggerModule.setup('docs', app, combinedDocument, {
    explorer: true,
    swaggerOptions: {
      urls: [
        { url: '/docs/v1-json', name: 'API v1' },
        { url: '/docs/v2-json', name: 'API v2' }
      ]
    }
  });
}

Environment-Based Configuration

function setupSwaggerBasedOnEnvironment(app: INestApplication, document: OpenAPIObject) {
  const isDevelopment = process.env.NODE_ENV === 'development';
  const isStaging = process.env.NODE_ENV === 'staging';
  const isProduction = process.env.NODE_ENV === 'production';

  if (isDevelopment) {
    // Full-featured documentation for development
    SwaggerModule.setup('api-docs', app, document, {
      explorer: true,
      swaggerOptions: {
        persistAuthorization: true,
        displayRequestDuration: true,
        tryItOutEnabled: true
      },
      customSiteTitle: 'Dev API Documentation'
    });
  } else if (isStaging) {
    // Limited documentation for staging
    SwaggerModule.setup('docs', app, document, {
      explorer: false,
      swaggerOptions: {
        tryItOutEnabled: false
      },
      customSiteTitle: 'Staging API Documentation'
    });
  } else if (isProduction) {
    // Minimal or no documentation for production
    if (process.env.ENABLE_DOCS === 'true') {
      SwaggerModule.setup('internal-docs', app, document, {
        ui: true,
        raw: ['json'], // Only JSON, no YAML
        swaggerOptions: {
          tryItOutEnabled: false,
          supportedSubmitMethods: [] // Disable try-it-out
        },
        customSiteTitle: 'Internal API Documentation'
      });
    }
    // Otherwise, no Swagger setup in production
  }
}

The SwaggerModule provides powerful, flexible integration between NestJS applications and Swagger UI, supporting everything from basic documentation needs to sophisticated multi-version, multi-environment setups with extensive customization options.

docs

decorators.md

document-builder.md

index.md

interfaces.md

swagger-module.md

type-helpers.md

tile.json