Doc Documentation
This documentation explains the features and usage of Doc Module: Located at src/common/doc
Overview
This module provides decorators for API documentation using Swagger/OpenAPI . It creates standardized, consistent API documentation with minimal boilerplate code.
Features:
- Standardized API documentation structure
- Automatic error response documentation
- Built-in pagination support
- File upload/download documentation
- Multiple authentication method support
- Request validation documentation
- Custom language header support
Related Documents
- Request Validation Documentation - For DTO validation and request documentation
- Response Documentation - For response structure and formatting
- Authentication Documentation - For authentication decorator usage
- Authorization Documentation - For authorization guard documentation
Table of Contents
Decorators
Doc
Basic API documentation decorator that sets up common operation metadata.
Parameters:
options?: IDocOptionssummary?: string- Operation summaryoperation?: string- Operation IDdeprecated?: boolean- Mark as deprecateddescription?: string- Detailed description
Auto-includes:
- Custom headers:
x-custom-lang- Customizable by frontend - Custom language header (default: EN)x-correlation-id- Customizable by frontend - Correlation identifier for tracking requests across servicesx-timestamp- Auto-included - Timestamp in millisecondsx-timezone- Auto-included - Timezone (e.g., Asia/Jakarta)x-version- Auto-included - API versionx-repo-version- Auto-included - Repository versionx-request-id- Auto-included - Unique request identifier (UUID)
- Standard error responses:
- Internal server error (500)
- Request timeout (408)
- Validation error (422)
- Environment forbidden error
- Parameter required error
Usage:
@Doc({
summary: 'Get user profile',
operation: 'getUserProfile',
description: 'Retrieve authenticated user profile information'
})
@Get('/profile')
async getProfile() {
// implementation
}DocRequest
Documents request specifications including body, parameters, and queries.
Parameters:
options?: IDocRequestOptionsparams?: ApiParamOptions[]- URL parametersqueries?: ApiQueryOptions[]- Query parametersbodyType?: EnumDocRequestBodyType- Request body content typedto?: ClassConstructor<T>- Request DTO class
Body Types:
enum EnumDocRequestBodyType {
JSON = 'json',
FORM_DATA = 'formData',
FORM_URLENCODED = 'formUrlencoded',
TEXT = 'text',
NONE = 'none',
}Auto-includes:
- Content-Type header based on bodyType (or ‘none’ if not specified)
Usage:
@DocRequest({
params: [
{
name: 'id',
required: true,
type: 'string'
}
],
queries: [
{
name: 'include',
required: false,
type: 'string'
}
],
bodyType: EnumDocRequestBodyType.JSON,
dto: UpdateUserDto
})
@Put('/:id')
async updateUser() {
// implementation
}DocRequestFile
Documents file upload endpoints with multipart/form-data.
Parameters:
options?: IDocRequestFileOptions- Same asDocRequestbut excludesbodyType
Auto-includes:
- Content-Type: multipart/form-data
- File-related error responses:
- File extension invalid error
- File required error
- File required extract first error
Usage:
@DocRequestFile({
params: [
{
name: 'id',
required: true,
type: 'string'
}
],
dto: UserUploadDto
})
@Post('/upload')
async uploadFile() {
// implementation
}DocResponse
Documents standard response with message and optional data.
Parameters:
messagePath: string- i18n message pathoptions?: IDocResponseOptions<T>statusCode?: number- Custom status codehttpStatus?: HttpStatus- HTTP status (default: 200)dto?: ClassConstructor<T>- Response DTO class
Auto-includes:
- Content-Type: application/json
- Standard response schema with message, statusCode, and data
Usage:
@DocResponse<UserProfileResponseDto>('user.get', {
dto: UserProfileResponseDto
})
@Get('/:id')
async getUser() {
// implementation
}
@DocResponse('user.delete', {
httpStatus: HttpStatus.NO_CONTENT
})
@Delete('/:id')
async deleteUser() {
// implementation
}DocResponsePaging
Documents paginated response with automatic pagination parameters.
Parameters:
messagePath: string- i18n message pathoptions: IDocResponsePagingOptions<T>type?: EnumPaginationType- Pagination type:offsetorcursor(default:offset)statusCode?: number- Custom status codehttpStatus?: HttpStatus- HTTP statusavailableSearch?: string[]- Searchable fieldsavailableOrder?: string[]- Sortable fields
Auto-includes:
- Standard pagination query parameters (depends on type):
- Offset type (default):
perPage- Data per page (max: 100)page- Page number (max: 20)
- Cursor type:
perPage- Data per page (max: 100)cursor- The pagination cursor returned from the previous request
- Offset type (default):
- Optional search query when
availableSearchprovided - Optional ordering queries when
availableOrderprovided:orderBy- Field to order byorderDirection- ASC or DESC
Usage:
// Offset pagination (default)
@DocResponsePaging<UserListResponseDto>('user.list', {
dto: UserListResponseDto,
availableSearch: ['name', 'email'],
availableOrder: ['createdAt', 'name']
})
@Get('/list')
async getUsers() {
// implementation
}
// Cursor pagination
@DocResponsePaging<UserListResponseDto>('user.list', {
dto: UserListResponseDto,
type: EnumPaginationType.CURSOR,
availableSearch: ['name', 'email'],
availableOrder: ['createdAt', 'name']
})
@Get('/list')
async getUsers() {
// implementation
}DocResponseFile
Documents file download/response endpoints.
Parameters:
options?: IDocResponseFileOptionshttpStatus?: HttpStatus- HTTP status (default: 200)extension?: EnumFileExtension- File extension (default: CSV)
Usage:
@DocResponseFile({
extension: EnumFileExtension.XLSX
})
@Get('/export')
async exportData() {
// implementation
}DocAuth
Documents authentication requirements and error responses.
Parameters:
options?: IDocAuthOptionsjwtAccessToken?: boolean- Require access tokenjwtRefreshToken?: boolean- Require refresh tokenxApiKey?: boolean- Require API keygoogle?: boolean- Require Google OAuthapple?: boolean- Require Apple OAuth
Auto-includes:
- Bearer auth or security scheme based on options
- Unauthorized error responses (401) for each auth method
Usage:
@DocAuth({
jwtAccessToken: true,
xApiKey: true
})
@Get('/protected')
async protectedRoute() {
// implementation
}
@DocAuth({
google: true,
xApiKey: true
})
@Post('/auth/google')
async googleLogin() {
// implementation
}DocGuard
Documents authorization guards and forbidden responses.
Parameters:
options?: IDocGuardOptionsrole?: boolean- Role-based guardpolicy?: boolean- Policy-based guardtermPolicy?: boolean- Term policy acceptance guard
Auto-includes:
- Forbidden error responses (403) based on guard types:
- If
roleis true, documents forbidden response for role-based access control. - If
policyis true, documents forbidden response for policy-based access control. - If
termPolicyis true, documents forbidden response for term policy acceptance.
- If
Usage:
@DocGuard({
role: true,
policy: true,
termPolicy: true
})
@Post('/admin/users')
async createUser() {
// implementation
}Advanced Decorators
DocDefault
Creates standard response schema with message, statusCode, and optional data.
Parameters:
options: IDocDefaultOptions<T>httpStatus: HttpStatus- HTTP status (required)messagePath: string- i18n message path (required)statusCode: number- Custom status code (required)dto?: ClassConstructor<T>- Response DTO class
Usage:
@DocDefault({
httpStatus: HttpStatus.CREATED,
messagePath: 'resource.created',
statusCode: HttpStatus.CREATED,
dto: CreatedResourceDto
})
@Post('/resource')
async createResource() {
// implementation
}DocOneOf
Documents endpoint that returns one of several possible response types using OpenAPI’s oneOf. Useful for documenting endpoints that can return different error types with the same HTTP status.
Parameters:
httpStatus: HttpStatus- HTTP status code...documents: IDocOfOptions[]- One or more possible response schemasstatusCode: number- Status codemessagePath: string- Message path for i18ndto?: ClassConstructor- Optional DTO class
Basic Usage:
DocOneOf(
HttpStatus.BAD_REQUEST,
{
statusCode: EnumUserStatus_CODE_ERROR.emailExist,
messagePath: 'user.error.emailExist',
},
{
statusCode: EnumUserStatus_CODE_ERROR.usernameExist,
messagePath: 'user.error.usernameExist',
}
)Detailed Examples:
For complete examples of DocOneOf usage in combination with other decorators, see:
DocAnyOf
Documents endpoint that can match any combination of provided schemas using OpenAPI’s anyOf. Useful when response can satisfy one or more schemas simultaneously.
Parameters:
httpStatus: HttpStatus- HTTP status code...documents: IDocOfOptions[]- Possible response schemasstatusCode: number- Status codemessagePath: string- Message path for i18ndto?: ClassConstructor- Optional DTO class
Basic Usage:
DocAnyOf(
HttpStatus.OK,
{
statusCode: HttpStatus.OK,
messagePath: 'user.partial',
dto: UserPartialDto,
},
{
statusCode: HttpStatus.OK,
messagePath: 'user.full',
dto: UserFullDto,
}
)DocAllOf
Documents endpoint that must satisfy all provided schema definitions using OpenAPI’s allOf. Useful for documenting responses that combine multiple schemas.
Parameters:
httpStatus: HttpStatus- HTTP status code...documents: IDocOfOptions[]- Required response schemas (all must be satisfied)statusCode: number- Status codemessagePath: string- Message path for i18ndto?: ClassConstructor- Optional DTO class
Basic Usage:
DocAllOf(
HttpStatus.OK,
{
statusCode: HttpStatus.OK,
messagePath: 'user.base',
dto: UserBaseDto,
},
{
statusCode: HttpStatus.OK,
messagePath: 'user.extended',
dto: UserExtendedDto,
}
)Swagger JSON
The ACK NestJS Boilerplate automatically generates the OpenAPI Swagger JSON documentation for your API. This file describes all endpoints, schemas, and metadata for integration, testing, or external documentation tools.
How to Get swagger.json
There are two ways to obtain the Swagger JSON file:
- Via URL (API Docs Endpoint):
- After starting the server, access:
/docs/json - Example:
http://localhost:3000/docs/json - This endpoint always serves the latest Swagger spec for the running app.
- Via Generated File:
- The file is auto-generated at:
generated/swagger.json - This file is written every time the app starts.
- You can use this file for CI/CD, external tools, or static documentation.
Both methods provide the same OpenAPI spec. Use whichever fits your workflow (dynamic via URL or static via file).
DTO Documentation
All decorators from @nestjs/swagger are fully supported in this module. This section provides an example using @ApiProperty, one of the most commonly used decorators for DTO documentation.
ApiProperty
The @ApiProperty decorator from @nestjs/swagger documents DTO properties. It supports all standard Swagger/OpenAPI property options.
Parameters:
For complete options reference, see NestJS Swagger Types documentation .
Common options:
description?: string- Property descriptionexample?: any- Example valuerequired?: boolean- Mark as requiredtype?: Type | string- Property typeenum?: any[]- Enum valuesminimum?: number- Minimum valuemaximum?: number- Maximum valueminLength?: number- Minimum string lengthmaxLength?: number- Maximum string lengthpattern?: string- Regex patterndefault?: any- Default valuenullable?: boolean- Allow nullreadOnly?: boolean- Read-only propertywriteOnly?: boolean- Write-only property
Usage:
export class UserChangePasswordRequestDto {
@ApiProperty({
description: "new string password, newPassword can't same with oldPassword",
example: 'aBcDe@Fgh!123',
required: true,
minLength: 8,
maxLength: 50,
})
@IsNotEmpty()
@IsString()
@IsPassword()
@MinLength(8)
@MaxLength(50)
newPassword: string;
@ApiProperty({
description: 'old string password',
example: 'xYzAb@Cde!456',
required: true,
})
@IsString()
@IsNotEmpty()
oldPassword: string;
}With Inheritance:
export class UserForgotPasswordResetRequestDto extends PickType(
UserChangePasswordRequestDto,
['newPassword'] as const
) {
@ApiProperty({
required: true,
description: 'Forgot password token',
example: 'AbCdEfGhIjKlMnOpQrSt',
})
@IsString()
@IsNotEmpty()
token: string;
}Usage
Complete Admin Endpoint
export function UserAdminGetDoc(): MethodDecorator {
return applyDecorators(
Doc({
summary: 'get detail an user',
}),
DocRequest({
params: UserDocParamsId,
}),
DocAuth({
xApiKey: true,
jwtAccessToken: true,
}),
DocGuard({ role: true, policy: true }),
DocResponse<UserProfileResponseDto>('user.get', {
dto: UserProfileResponseDto,
})
);
}
@UserAdminGetDoc()
@Get('/:id')
async getUser(@Param('id') id: string) {
// implementation
}Complete Public Endpoint
export function UserPublicSignUpDoc(): MethodDecorator {
return applyDecorators(
Doc({
summary: 'User sign up',
}),
DocRequest({
bodyType: EnumDocRequestBodyType.JSON,
dto: UserSignUpRequestDto,
}),
DocAuth({
xApiKey: true,
}),
DocResponse('user.signUp', {
httpStatus: HttpStatus.CREATED,
})
);
}
@UserPublicSignUpDoc()
@Post('/sign-up')
async signUp(@Body() dto: UserSignUpRequestDto) {
// implementation
}Paginated List Endpoint
export function UserAdminListDoc(): MethodDecorator {
return applyDecorators(
Doc({
summary: 'get all users',
}),
DocRequest({
queries: UserDocQueryList,
}),
DocAuth({
xApiKey: true,
jwtAccessToken: true,
}),
DocGuard({ role: true, policy: true }),
DocResponsePaging<UserListResponseDto>('user.list', {
dto: UserListResponseDto,
availableSearch: ['name', 'email', 'username'],
availableOrder: ['createdAt', 'updatedAt', 'name']
})
);
}
@UserAdminListDoc()
@Get('/list')
async listUsers(@Query() query: PaginationQuery) {
// implementation
}File Upload Endpoint
export function UserUploadAvatarDoc(): MethodDecorator {
return applyDecorators(
Doc({
summary: 'Upload user avatar',
}),
DocRequestFile({
dto: FileUploadDto,
}),
DocAuth({
jwtAccessToken: true,
}),
DocResponse('user.uploadAvatar')
);
}
@UserUploadAvatarDoc()
@Post('/avatar')
async uploadAvatar(@UploadedFile() file: Express.Multer.File) {
// implementation
}For more information about NestJS Swagger integration, see the official NestJS documentation .