Skip to content

NestJS Integration ​

Tspec supports generating OpenAPI specifications directly from NestJS controllers. This allows you to automatically generate API documentation without manually defining type specifications.

Prerequisites ​

Before using NestJS integration, make sure you have:

  • A NestJS project with TypeScript
  • Controllers using NestJS decorators (@Controller, @Get, @Post, etc.)

Installation ​

Install tspec in your NestJS project:

bash
yarn add tspec
bash
npm install tspec
bash
pnpm add tspec

Basic Usage ​

Example Controller ​

Assume you have the following NestJS controller:

ts
import { Controller, Get, Post, Put, Delete, Param, Query, Body } from '@nestjs/common';

interface Book {
  id: number;
  title: string;
  author: string;
}

interface CreateBookDto {
  title: string;
  author: string;
}

interface BookListQuery {
  page?: number;
  limit?: number;
}

/**
 * Books API Controller
 */
@Controller('books')
export class BooksController {
  /**
   * Get all books with pagination
   * @summary List all books
   */
  @Get()
  findAll(@Query() query: BookListQuery): Promise<Book[]> {
    // implementation
  }

  /**
   * Get a single book by ID
   * @summary Get book by ID
   */
  @Get(':id')
  findOne(@Param('id') id: string): Promise<Book> {
    // implementation
  }

  /**
   * Create a new book
   * @summary Create book
   */
  @Post()
  create(@Body() createBookDto: CreateBookDto): Promise<Book> {
    // implementation
  }

  /**
   * Update an existing book
   * @summary Update book
   */
  @Put(':id')
  update(
    @Param('id') id: string,
    @Body() updateBookDto: CreateBookDto,
  ): Promise<Book> {
    // implementation
  }

  /**
   * Delete a book
   * @summary Delete book
   */
  @Delete(':id')
  remove(@Param('id') id: string): Promise<void> {
    // implementation
  }
}

Generate OpenAPI Spec ​

Generate OpenAPI specification directly from your NestJS controllers using the --nestjs flag:

bash
yarn tspec generate --nestjs
bash
npx tspec generate --nestjs
bash
pnpm tspec generate --nestjs
Generated OpenAPI Spec
yaml
openapi: 3.0.3
info:
  title: NestJS API
  version: 1.0.0
paths:
  /books:
    get:
      operationId: BooksController_findAll
      summary: List all books
      description: Get all books with pagination
      tags:
        - Books
      parameters:
        - name: page
          in: query
          required: false
          schema:
            type: number
        - name: limit
          in: query
          required: false
          schema:
            type: number
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Book'
    post:
      operationId: BooksController_create
      summary: Create book
      tags:
        - Books
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBookDto'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
  /books/{id}:
    get:
      operationId: BooksController_findOne
      summary: Get book by ID
      tags:
        - Books
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
    put:
      operationId: BooksController_update
      summary: Update book
      tags:
        - Books
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBookDto'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
    delete:
      operationId: BooksController_remove
      summary: Delete book
      tags:
        - Books
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: No Content

CLI Options ​

When using --nestjs flag, the following options are available:

OptionDefaultDescription
--nestjsfalseEnable NestJS controller parsing
--tsconfigPathtsconfig.jsonPath to TypeScript config file
--specPathGlobssrc/**/*.controller.tsGlob patterns to find controller files
--outputPathopenapi.jsonOutput path for generated OpenAPI spec
--openapiTitleTspec APIAPI title in OpenAPI info
--openapiVersion0.0.1API version in OpenAPI info
--openapiDescription``API description in OpenAPI info

Example with all options ​

bash
npx tspec generate --nestjs \
  --tsconfigPath tsconfig.json \
  --specPathGlobs 'src/**/*.controller.ts' \
  --outputPath docs/openapi.json \
  --openapiTitle 'My NestJS API' \
  --openapiVersion '2.0.0' \
  --openapiDescription 'API documentation for my NestJS application'

Supported Decorators ​

Tspec parses the following NestJS decorators:

Controller Decorators ​

  • @Controller(path?) - Defines the base path for all routes in the controller

HTTP Method Decorators ​

  • @Get(path?)
  • @Post(path?)
  • @Put(path?)
  • @Patch(path?)
  • @Delete(path?)
  • @Options(path?)
  • @Head(path?)

Parameter Decorators ​

  • @Param(name?) - Path parameters
  • @Query() - Query parameters
  • @Body() - Request body
  • @Headers() - Header parameters

Swagger Decorators ​

  • @ApiTags(...tags) - Adds tags to all operations in the controller
  • @ApiResponse({ status, description?, type? }) - Defines response status codes and types

JSDoc Support ​

Tspec extracts documentation from JSDoc comments:

ts
/**
 * This becomes the operation description
 * @summary This becomes the operation summary
 * @tag CustomTag
 */
@Get()
findAll(): Promise<Book[]> {
  // ...
}

Limitations ​

The current NestJS integration has some limitations:

  1. Type inference: Complex generic types may not be fully resolved
  2. Custom decorators: Only standard NestJS decorators are supported
  3. Validation decorators: class-validator decorators are not parsed
  4. Interceptors/Guards: These are not reflected in the generated spec

TIP

For more advanced use cases, consider using the standard Tspec approach with Tspec.DefineApiSpec alongside your NestJS controllers.

Programmatic API ​

You can generate OpenAPI specs programmatically using the generateTspec function with nestjs: true:

ts
import { generateTspec } from 'tspec';

const spec = await generateTspec({
  tsconfigPath: './tsconfig.json',
  specPathGlobs: ['src/**/*.controller.ts'],
  nestjs: true,
  openapi: {
    title: 'My API',
    version: '1.0.0',
    description: 'My NestJS API documentation',
  },
});

// Use the spec object directly or write to file
console.log(JSON.stringify(spec, null, 2));

Options ​

OptionTypeDefaultDescription
tsconfigPathstring./tsconfig.jsonPath to TypeScript config file
specPathGlobsstring[]['src/**/*.controller.ts']Glob patterns to find controller files
nestjsbooleanfalseEnable NestJS controller parsing mode
outputPathstring-Output path for generated OpenAPI spec
openapi.titlestringTspec APIAPI title
openapi.versionstring0.0.1API version
openapi.descriptionstring-API description
openapi.securityDefinitionsobject-Security schemes
openapi.serversarray-Server URLs

Using @ApiResponse ​

Tspec supports the @ApiResponse decorator from @nestjs/swagger to define multiple response types:

ts
import { Controller, Get, Param } from '@nestjs/common';
import { ApiResponse } from '@nestjs/swagger';

class Book {
  id: number;
  title: string;
  author: string;
}

class ErrorResponse {
  message: string;
  statusCode: number;
}

@Controller('books')
export class BooksController {
  @Get(':id')
  @ApiResponse({ status: 200, description: 'Book found', type: Book })
  @ApiResponse({ status: 404, description: 'Book not found', type: ErrorResponse })
  @ApiResponse({ status: 500, description: 'Internal server error' })
  findOne(@Param('id') id: string): Promise<Book> {
    // implementation
  }
}

This generates the following responses in OpenAPI:

yaml
responses:
  '200':
    description: Book found
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/Book'
  '404':
    description: Book not found
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/ErrorResponse'
  '500':
    description: Internal server error

TIP

When @ApiResponse decorators are present, they override the default response generation based on return type.

Using @ApiTags ​

Tspec supports the @ApiTags decorator from @nestjs/swagger to organize your API operations:

ts
import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';

@ApiTags('Users', 'Admin')
@Controller('users')
export class UsersController {
  @Get()
  findAll(): Promise<User[]> {
    // This operation will have tags: ['Users', 'Admin']
  }
}

You can also use enum values or constants:

ts
enum ApiTag {
  USERS = 'users',
  ADMIN = 'admin',
}

@ApiTags(ApiTag.USERS, ApiTag.ADMIN)
@Controller('users')
export class UsersController {
  // ...
}

Combining with Standard Tspec ​

You can use both approaches in the same project:

  1. Use --nestjs flag for quick documentation of existing controllers
  2. Use Tspec.DefineApiSpec for APIs that need more detailed specifications
bash
# Generate from NestJS controllers
npx tspec generate --nestjs --outputPath openapi-nest.json

# Generate from Tspec definitions
npx tspec generate --outputPath openapi-tspec.json