OpenAPI (Swagger) module for Nest framework enabling automatic API documentation generation from TypeScript decorators
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The @nestjs/swagger decorators provide a comprehensive annotation system for adding OpenAPI metadata to your NestJS applications. These TypeScript decorators attach metadata to classes, methods, properties, and parameters that is then used to generate accurate OpenAPI specifications.
Property decorators are used to annotate class properties, typically in DTOs (Data Transfer Objects) and entity classes.
import { ApiProperty } from '@nestjs/swagger';
ApiProperty(options?: ApiPropertyOptions): PropertyDecoratorMarks a class property as an OpenAPI schema property with optional metadata configuration.
Type Definitions:
type ApiPropertyOptions = ApiPropertyCommonOptions | (ApiPropertyCommonOptions & {
enumName: string;
enumSchema?: EnumSchemaAttributes;
});
type ApiPropertyCommonOptions = SchemaObjectMetadata & {
'x-enumNames'?: string[];
link?: () => Type<unknown> | Function;
};
interface SchemaObjectMetadata {
type?: any;
isArray?: boolean;
description?: string;
required?: boolean;
default?: any;
example?: any;
format?: string;
minimum?: number;
maximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
enum?: any[];
enumName?: string;
deprecated?: boolean;
readOnly?: boolean;
writeOnly?: boolean;
nullable?: boolean;
discriminator?: DiscriminatorObject;
xml?: XMLObject;
additionalProperties?: boolean | SchemaObject;
items?: SchemaObject;
allOf?: SchemaObject[];
oneOf?: SchemaObject[];
anyOf?: SchemaObject[];
not?: SchemaObject;
}Usage:
class CreateProductDto {
@ApiProperty({
description: 'Product name',
example: 'iPhone 15',
minLength: 1,
maxLength: 100
})
name: string;
@ApiProperty({
description: 'Product price',
example: 999.99,
minimum: 0
})
price: number;
@ApiProperty({
description: 'Product category',
enum: ['electronics', 'clothing', 'books'],
example: 'electronics'
})
category: string;
@ApiProperty({
description: 'Product tags',
type: [String],
isArray: true,
example: ['mobile', 'apple', 'smartphone']
})
tags: string[];
}import { ApiPropertyOptional } from '@nestjs/swagger';
ApiPropertyOptional(options?: ApiPropertyOptions): PropertyDecoratorCreates an optional property annotation. Equivalent to @ApiProperty({ required: false, ...options }).
Usage:
class UpdateProductDto {
@ApiPropertyOptional({ description: 'Updated product name' })
name?: string;
@ApiPropertyOptional({ description: 'Updated product price' })
price?: number;
@ApiPropertyOptional({ description: 'Product availability' })
inStock?: boolean;
}import { ApiResponseProperty } from '@nestjs/swagger';
ApiResponseProperty(options?: Pick<ApiPropertyOptions, 'type' | 'example' | 'format' | 'deprecated' | 'enum'>): PropertyDecoratorCreates a read-only response property. Used for properties that only appear in API responses.
Usage:
class ProductResponseDto {
@ApiResponseProperty({
example: 'prod_123456',
description: 'Unique product identifier'
})
readonly id: string;
@ApiResponseProperty({
example: '2023-01-15T10:30:00Z',
format: 'date-time'
})
readonly createdAt: Date;
@ApiResponseProperty({
example: '2023-01-16T14:20:00Z',
format: 'date-time'
})
readonly updatedAt: Date;
}import { ApiHideProperty } from '@nestjs/swagger';
ApiHideProperty(): PropertyDecoratorExcludes a property from the OpenAPI specification. Useful for sensitive or internal properties.
Usage:
class UserDto {
@ApiProperty()
email: string;
@ApiHideProperty()
password: string; // Won't appear in OpenAPI spec
@ApiHideProperty()
internalId: number; // Hidden from documentation
}Method decorators annotate controller methods and endpoints with OpenAPI operation metadata.
import { ApiOperation } from '@nestjs/swagger';
ApiOperation(options: ApiOperationOptions, opts?: { overrideExisting?: boolean }): MethodDecoratorDescribes an API operation (HTTP endpoint) with summary, description, and other metadata.
Type Definitions:
type ApiOperationOptions = Partial<OperationObject>;
interface OperationObject {
summary?: string;
description?: string;
operationId?: string;
tags?: string[];
deprecated?: boolean;
security?: SecurityRequirementObject[];
externalDocs?: ExternalDocumentationObject;
callbacks?: Record<string, CallbackObject | ReferenceObject>;
}Usage:
@Controller('products')
export class ProductsController {
@Get()
@ApiOperation({
summary: 'Get all products',
description: 'Retrieves a paginated list of all available products',
operationId: 'getProducts'
})
findAll() {}
@Post()
@ApiOperation({
summary: 'Create product',
description: 'Creates a new product with the provided data'
})
create() {}
@Delete(':id')
@ApiOperation({
summary: 'Delete product',
description: 'Permanently deletes a product by ID',
deprecated: true
})
remove() {}
}import { ApiResponse } from '@nestjs/swagger';
ApiResponse(options: ApiResponseOptions, opts?: { overrideExisting?: boolean }): MethodDecorator & ClassDecoratorDefines response metadata for an endpoint, including status code, description, and schema.
Type Definitions:
interface ApiResponseOptions {
status?: number | 'default' | '1XX' | '2XX' | '3XX' | '4XX' | '5XX';
description?: string;
type?: any;
isArray?: boolean;
schema?: SchemaObject & Partial<ReferenceObject>;
headers?: Record<string, HeaderObject>;
content?: Record<string, MediaTypeObject>;
links?: Record<string, LinkObject>;
}Usage:
@Controller('products')
export class ProductsController {
@Get()
@ApiResponse({
status: 200,
description: 'Products retrieved successfully',
type: [ProductDto],
isArray: true
})
@ApiResponse({
status: 404,
description: 'No products found'
})
findAll() {}
@Post()
@ApiResponse({
status: 201,
description: 'Product created successfully',
type: ProductDto
})
@ApiResponse({
status: 400,
description: 'Invalid product data',
schema: {
type: 'object',
properties: {
error: { type: 'string' },
message: { type: 'string' }
}
}
})
create() {}
}Pre-configured response decorators for common HTTP status codes:
import {
// 1xx Informational responses
ApiContinueResponse, // 100
ApiSwitchingProtocolsResponse, // 101
ApiProcessingResponse, // 102
ApiEarlyhintsResponse, // 103
// 2xx Success responses
ApiOkResponse, // 200
ApiCreatedResponse, // 201
ApiAcceptedResponse, // 202
ApiNonAuthoritativeInformationResponse, // 203
ApiNoContentResponse, // 204
ApiResetContentResponse, // 205
ApiPartialContentResponse, // 206
// 3xx Redirection responses
ApiAmbiguousResponse, // 300
ApiMovedPermanentlyResponse, // 301
ApiFoundResponse, // 302
ApiSeeOtherResponse, // 303
ApiNotModifiedResponse, // 304
ApiTemporaryRedirectResponse, // 307
ApiPermanentRedirectResponse, // 308
// 4xx Client error responses
ApiBadRequestResponse, // 400
ApiUnauthorizedResponse, // 401
ApiPaymentRequiredResponse, // 402
ApiForbiddenResponse, // 403
ApiNotFoundResponse, // 404
ApiMethodNotAllowedResponse, // 405
ApiNotAcceptableResponse, // 406
ApiProxyAuthenticationRequiredResponse, // 407
ApiRequestTimeoutResponse, // 408
ApiConflictResponse, // 409
ApiGoneResponse, // 410
ApiLengthRequiredResponse, // 411
ApiPreconditionFailedResponse, // 412
ApiPayloadTooLargeResponse, // 413
ApiUriTooLongResponse, // 414
ApiUnsupportedMediaTypeResponse, // 415
ApiRequestedRangeNotSatisfiableResponse, // 416
ApiExpectationFailedResponse, // 417
ApiIAmATeapotResponse, // 418
ApiMisdirectedResponse, // 421
ApiUnprocessableEntityResponse, // 422
ApiFailedDependencyResponse, // 424
ApiPreconditionRequiredResponse, // 428
ApiTooManyRequestsResponse, // 429
// 5xx Server error responses
ApiInternalServerErrorResponse, // 500
ApiNotImplementedResponse, // 501
ApiBadGatewayResponse, // 502
ApiServiceUnavailableResponse, // 503
ApiGatewayTimeoutResponse, // 504
ApiHttpVersionNotSupportedResponse // 505
} from '@nestjs/swagger';
// All have the same signature:
ApiOkResponse(options?: ApiResponseNoStatusOptions): MethodDecorator & ClassDecorator
type ApiResponseNoStatusOptions = Omit<ApiResponseOptions, 'status'>;Usage:
@Controller('products')
export class ProductsController {
@Get()
@ApiOkResponse({
description: 'Products retrieved successfully',
type: [ProductDto]
})
@ApiNotFoundResponse({ description: 'No products found' })
findAll() {}
@Post()
@ApiCreatedResponse({
description: 'Product created successfully',
type: ProductDto
})
@ApiBadRequestResponse({ description: 'Invalid product data' })
create() {}
@Delete(':id')
@ApiNoContentResponse({ description: 'Product deleted successfully' })
@ApiNotFoundResponse({ description: 'Product not found' })
remove() {}
}import { ApiDefaultResponse } from '@nestjs/swagger';
ApiDefaultResponse(options?: ApiResponseNoStatusOptions): MethodDecorator & ClassDecoratorDefines a default response that applies to all status codes not explicitly documented.
Usage:
@Controller('products')
export class ProductsController {
@Get()
@ApiOkResponse({ type: [ProductDto] })
@ApiDefaultResponse({ description: 'Unexpected error occurred' })
findAll() {}
}Parameter decorators describe the various types of parameters accepted by API endpoints.
import { ApiParam } from '@nestjs/swagger';
ApiParam(options: ApiParamOptions): ParameterDecoratorDescribes a path parameter in the URL.
Type Definitions:
interface ApiParamOptions {
name?: string;
description?: string;
required?: boolean;
type?: any;
enum?: any[];
example?: any;
examples?: Record<string, any>;
schema?: SchemaObject;
allowEmptyValue?: boolean;
style?: ParameterStyle;
explode?: boolean;
allowReserved?: boolean;
}Usage:
@Controller('products')
export class ProductsController {
@Get(':id')
@ApiParam({
name: 'id',
description: 'Product unique identifier',
type: 'string',
example: 'prod_123456'
})
findOne(@Param('id') id: string) {}
@Get('category/:category')
@ApiParam({
name: 'category',
description: 'Product category',
enum: ['electronics', 'clothing', 'books'],
example: 'electronics'
})
findByCategory(@Param('category') category: string) {}
}import { ApiQuery } from '@nestjs/swagger';
ApiQuery(options: ApiQueryOptions): ParameterDecoratorDescribes a query parameter in the URL.
Type Definitions:
interface ApiQueryOptions extends ApiParamOptions {
name?: string;
required?: boolean;
type?: any;
isArray?: boolean;
}Usage:
@Controller('products')
export class ProductsController {
@Get()
@ApiQuery({
name: 'limit',
description: 'Maximum number of products to return',
required: false,
type: Number,
example: 10
})
@ApiQuery({
name: 'offset',
description: 'Number of products to skip',
required: false,
type: Number,
example: 0
})
@ApiQuery({
name: 'categories',
description: 'Filter by categories',
required: false,
type: [String],
isArray: true,
example: ['electronics', 'books']
})
findAll(
@Query('limit') limit?: number,
@Query('offset') offset?: number,
@Query('categories') categories?: string[]
) {}
}import { ApiBody } from '@nestjs/swagger';
ApiBody(options: ApiBodyOptions): MethodDecoratorDescribes the request body content and schema.
Type Definitions:
interface ApiBodyOptions {
description?: string;
type?: any;
isArray?: boolean;
required?: boolean;
schema?: SchemaObject & Partial<ReferenceObject>;
examples?: Record<string, any>;
}Usage:
@Controller('products')
export class ProductsController {
@Post()
@ApiBody({
description: 'Product data to create',
type: CreateProductDto,
examples: {
example1: {
summary: 'Basic product',
value: {
name: 'iPhone 15',
price: 999.99,
category: 'electronics'
}
}
}
})
create(@Body() createProductDto: CreateProductDto) {}
@Post('bulk')
@ApiBody({
description: 'Array of products to create',
type: [CreateProductDto],
isArray: true
})
createBulk(@Body() products: CreateProductDto[]) {}
}import { ApiHeader } from '@nestjs/swagger';
ApiHeader(options: ApiHeaderOptions): MethodDecorator & ClassDecoratorDescribes a header parameter required by the endpoint.
Type Definitions:
interface ApiHeaderOptions {
name?: string;
description?: string;
required?: boolean;
schema?: SchemaObject;
example?: any;
examples?: Record<string, any>;
}Usage:
@Controller('products')
export class ProductsController {
@Post()
@ApiHeader({
name: 'X-API-Key',
description: 'API key for authentication',
required: true,
example: 'abc123def456'
})
@ApiHeader({
name: 'Content-Language',
description: 'Preferred language for response',
required: false,
example: 'en-US'
})
create(@Body() createProductDto: CreateProductDto) {}
}import { ApiHeaders } from '@nestjs/swagger';
ApiHeaders(headers: ApiHeaderOptions[]): MethodDecorator & ClassDecoratorApplies multiple header parameters at once using an array of header options.
Usage:
@Controller('products')
export class ProductsController {
@Post()
@ApiHeaders([
{
name: 'X-API-Key',
description: 'API key for authentication',
required: true,
example: 'abc123def456'
},
{
name: 'Content-Language',
description: 'Preferred language for response',
required: false,
example: 'en-US'
},
{
name: 'X-Request-ID',
description: 'Unique request identifier',
required: false,
example: 'req_12345'
}
])
create(@Body() createProductDto: CreateProductDto) {}
}import { ApiCookieAuth } from '@nestjs/swagger';
ApiCookieAuth(name = 'cookie'): MethodDecorator & ClassDecoratorDescribes a cookie parameter used by the endpoint.
Type Definitions:
interface ApiCookieOptions {
name?: string;
description?: string;
required?: boolean;
schema?: SchemaObject;
example?: any;
}Usage:
@Controller('products')
export class ProductsController {
@Get()
@ApiCookieAuth('session') // Cookie-based authentication
findUserProducts() {}
}import { ApiConsumes } from '@nestjs/swagger';
ApiConsumes(...mimeTypes: string[]): MethodDecorator & ClassDecoratorSpecifies the MIME types that the operation can consume in request bodies.
Usage:
@Controller('uploads')
export class UploadsController {
@Post('image')
@ApiConsumes('multipart/form-data', 'image/jpeg', 'image/png')
uploadImage(@Body() data: any) {}
@Post('document')
@ApiConsumes('application/pdf', 'application/msword')
uploadDocument(@Body() data: any) {}
}import { ApiProduces } from '@nestjs/swagger';
ApiProduces(...mimeTypes: string[]): MethodDecorator & ClassDecoratorSpecifies the MIME types that the operation can produce in responses.
Usage:
@Controller('products')
export class ProductsController {
@Get(':id/image')
@ApiProduces('image/jpeg', 'image/png', 'image/webp')
getProductImage(@Param('id') id: string) {}
@Get('export')
@ApiProduces('application/json', 'text/csv', 'application/xlsx')
exportProducts(@Query('format') format: string) {}
}import { ApiSecurity } from '@nestjs/swagger';
ApiSecurity(name: string, requirements?: string[]): MethodDecorator & ClassDecoratorApplies a security requirement to an operation or controller.
Usage:
@Controller('admin')
@ApiSecurity('bearer') // Applies to all endpoints in controller
export class AdminController {
@Get('users')
@ApiSecurity('api-key') // Additional security for this endpoint
getUsers() {}
@Post('users')
@ApiSecurity('oauth2', ['admin:write']) // OAuth2 with specific scopes
createUser() {}
}import { ApiBearerAuth } from '@nestjs/swagger';
ApiBearerAuth(name?: string): MethodDecorator & ClassDecoratorApplies Bearer token authentication (JWT) to an endpoint or controller.
Usage:
@Controller('products')
@ApiBearerAuth() // Default name: 'bearer'
export class ProductsController {
@Get()
findAll() {} // Requires Bearer token
@Post()
@ApiBearerAuth('admin-bearer') // Custom security scheme name
create() {}
}import { ApiBasicAuth } from '@nestjs/swagger';
ApiBasicAuth(name?: string): MethodDecorator & ClassDecoratorApplies HTTP Basic authentication to an endpoint or controller.
Usage:
@Controller('legacy')
@ApiBasicAuth() // Default name: 'basic'
export class LegacyController {
@Get()
getData() {} // Requires Basic auth
@Post()
@ApiBasicAuth('admin-basic') // Custom security scheme name
createData() {}
}import { ApiOAuth2 } from '@nestjs/swagger';
ApiOAuth2(scopes?: string[], name?: string): MethodDecorator & ClassDecoratorApplies OAuth2 authentication with optional scopes to an endpoint or controller.
Usage:
@Controller('api')
export class ApiController {
@Get('public')
getPublicData() {} // No auth required
@Get('user')
@ApiOAuth2(['read']) // OAuth2 with read scope
getUserData() {}
@Post('admin')
@ApiOAuth2(['read', 'write', 'admin'], 'oauth2') // Multiple scopes
adminAction() {}
}import { ApiTags } from '@nestjs/swagger';
ApiTags(...tags: string[]): MethodDecorator & ClassDecoratorGroups operations by tags in the Swagger UI for better organization.
Usage:
@Controller('products')
@ApiTags('Products') // All endpoints tagged as 'Products'
export class ProductsController {
@Get()
findAll() {}
@Post()
@ApiTags('Products', 'Admin') // Multiple tags
create() {}
}
@Controller('users')
@ApiTags('User Management', 'Authentication')
export class UsersController {}import { ApiExcludeEndpoint } from '@nestjs/swagger';
ApiExcludeEndpoint(disable?: boolean): MethodDecoratorExcludes a specific endpoint from the OpenAPI specification.
Usage:
@Controller('products')
export class ProductsController {
@Get()
findAll() {} // Included in OpenAPI
@Get('internal')
@ApiExcludeEndpoint() // Excluded from OpenAPI
internalEndpoint() {}
@Get('debug')
@ApiExcludeEndpoint(process.env.NODE_ENV === 'production') // Conditional exclusion
debugEndpoint() {}
}import { ApiExcludeController } from '@nestjs/swagger';
ApiExcludeController(disable?: boolean): ClassDecoratorExcludes an entire controller from the OpenAPI specification.
Usage:
@Controller('internal')
@ApiExcludeController() // Entire controller excluded
export class InternalController {
@Get()
internalData() {} // Not in OpenAPI
@Post()
internalAction() {} // Not in OpenAPI
}
@Controller('debug')
@ApiExcludeController(process.env.NODE_ENV === 'production')
export class DebugController {} // Excluded in production onlyimport { ApiExtraModels } from '@nestjs/swagger';
ApiExtraModels(...models: Function[]): ClassDecoratorAdds extra models to the OpenAPI components section for reference in schemas.
Usage:
@Controller('products')
@ApiExtraModels(ProductDto, CategoryDto, TagDto) // Models available for $ref
export class ProductsController {
@Get()
@ApiResponse({
status: 200,
schema: {
allOf: [
{ $ref: getSchemaPath(ProductDto) },
{
properties: {
category: { $ref: getSchemaPath(CategoryDto) },
tags: {
type: 'array',
items: { $ref: getSchemaPath(TagDto) }
}
}
}
]
}
})
findAll() {}
}import { ApiExtension } from '@nestjs/swagger';
ApiExtension(extensionKey: string, extensionProperties: any): MethodDecorator & ClassDecoratorAdds custom OpenAPI extensions (x-* properties) to operations or schemas.
Usage:
@Controller('products')
export class ProductsController {
@Get()
@ApiExtension('x-codeSamples', [
{
lang: 'JavaScript',
source: 'const products = await api.getProducts();'
},
{
lang: 'Python',
source: 'products = api.get_products()'
}
])
findAll() {}
@Post()
@ApiExtension('x-rate-limit', { requests: 100, window: '1h' })
create() {}
}import { ApiSchema } from '@nestjs/swagger';
ApiSchema(options?: ApiSchemaOptions): ClassDecoratorDefines custom schema metadata for a class, overriding auto-generated schema properties.
Type Definitions:
interface ApiSchemaOptions {
name?: string;
description?: string;
deprecated?: boolean;
discriminator?: DiscriminatorObject;
additionalProperties?: boolean | SchemaObject;
example?: any;
}Usage:
@ApiSchema({
name: 'Product',
description: 'A product in the system',
example: {
id: 'prod_123',
name: 'iPhone 15',
price: 999.99
}
})
export class ProductDto {
@ApiProperty()
id: string;
@ApiProperty()
name: string;
@ApiProperty()
price: number;
}import { ApiCallbacks } from '@nestjs/swagger';
ApiCallbacks(...callbackObjects: Array<CallBackObject<any>>): MethodDecoratorDefines callback objects for asynchronous operations like webhooks.
Type Definitions:
interface CallBackObject<T> {
name: string;
callbackUrl: string;
method: string;
requestBody: {
type: T;
};
expectedResponse: {
status: number;
description?: string;
};
}Usage:
@Controller('webhooks')
export class WebhookController {
@Post('subscribe')
@ApiCallbacks(
{
name: 'orderUpdate',
callbackUrl: 'http://callback.example.com/order-update',
method: 'post',
requestBody: {
type: OrderUpdateDto
},
expectedResponse: {
status: 200,
description: 'Callback received successfully'
}
},
{
name: 'paymentNotification',
callbackUrl: 'http://callback.example.com/payment-notification',
method: 'post',
requestBody: {
type: PaymentNotificationDto
},
expectedResponse: {
status: 200
}
}
)
subscribe() {}
}import { ApiLink } from '@nestjs/swagger';
ApiLink(options: ApiLinkOptions): PropertyDecoratorCreates OpenAPI link objects for describing relationships between operations.
Type Definitions:
interface ApiLinkOptions {
operationId?: string;
description?: string;
parameters?: Record<string, any>;
requestBody?: any;
}Usage:
class ProductDto {
@ApiProperty()
@ApiLink({
operationId: 'getProductById',
description: 'Link to get full product details'
})
id: string;
@ApiProperty()
name: string;
}import { ApiDefaultGetter } from '@nestjs/swagger';
ApiDefaultGetter(type: Type<unknown> | Function, parameter: string): MethodDecoratorMarks a method as the default getter for OpenAPI link generation with Swagger link objects.
Parameters:
type - The type for which the decorated function is the default getterparameter - Name of the parameter in the route that corresponds to the id of the typeUsage:
import { Type } from '@nestjs/common';
class UserGet {
id: string;
name: string;
}
@Controller('users')
export class UsersController {
@Get(':userId')
@ApiDefaultGetter(UserGet, 'userId') // Links UserGet type to this getter
@ApiOperation({ operationId: 'getUserById' })
findOne(@Param('userId') userId: string) {}
}@Controller('products')
@ApiTags('Products')
@ApiExtraModels(ProductDto, CreateProductDto, UpdateProductDto)
export class ProductsController {
@Get()
@ApiOperation({
summary: 'Get all products',
description: 'Retrieves a paginated list of all products with optional filtering'
})
@ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number })
@ApiOkResponse({ type: [ProductDto], description: 'Products retrieved successfully' })
@ApiBadRequestResponse({ description: 'Invalid query parameters' })
async findAll(@Query() query: PaginationDto) {}
@Post()
@ApiOperation({ summary: 'Create product' })
@ApiBody({ type: CreateProductDto })
@ApiCreatedResponse({ type: ProductDto })
@ApiBadRequestResponse({ description: 'Invalid product data' })
@ApiBearerAuth()
async create(@Body() createProductDto: CreateProductDto) {}
}class CreateProductDto {
@ApiProperty({
description: 'Product name',
minLength: 1,
maxLength: 100,
example: 'iPhone 15'
})
name: string;
@ApiProperty({
description: 'Product description',
maxLength: 1000,
example: 'Latest iPhone with advanced features'
})
description: string;
@ApiProperty({
description: 'Product price in USD',
minimum: 0,
example: 999.99
})
price: number;
@ApiPropertyOptional({
description: 'Product availability',
default: true
})
inStock?: boolean;
}This comprehensive decorator system provides everything needed to create detailed, accurate OpenAPI documentation for your NestJS applications with minimal effort while maintaining full type safety.