-
Notifications
You must be signed in to change notification settings - Fork 3
Swagger documentation
What is Swagger?
Swagger is an open-source framework that allows developers to design, build, document, and consume RESTful web services. It simplifies the process of designing and documenting APIs for web applications. The Swagger framework includes a set of tools that help developers define the structure of their APIs in a standard format, generate documentation automatically.
Why do we need Swagger documentation?
- Developer Experience: First and foremost, Swagger generates interactive and human-readable documentation for our API. This documentation is automatically generated from file and provides a clear and structured overview of the API's resources, operations, parameters, request/response formats, and more. This makes it easier for developers (especially for front-end developers) to understand how to use the API effectively.
- Communication: Swagger documentation serves as a clear and shared reference point for developers, testers, product managers, and other stakeholders involved in the API development process. It helps in aligning understanding and expectations among team members.
You should use the following decorators:
- @ApiTags(tagName: string)
- @ApiOkResponse()
- @ApiBadRequestResponse
- @ApiUnauthorizedResponse()
- @ApiForbiddenResponse()
- @ApiBearerAuth()
- @ApiBasicAuth()
- @ApiParam()
- @ApiQuery()
- @ApiPropery()
@ApiEndpoint is a custom decorator that provides a single interface for specifying a summary, permissions, and guards. This decorator takes an ApiEndpointParams object as a parameter, which contains the following fields:
- summary: Brief description of the endpoint -> Required
- permissions: Permissions required to access the endpoint -> Optional (if it is needed)
- guards: The guards that are applied to the enpoint, e.g TelegramGuard or JwtGuard -> Optional (if it is needed)
Example with permissions
@ApiEndpoint({
summary: 'Request to update a student',
permissions: PERMISSION.USERS_$USERID_STUDENT_UPDATE,
})
@Patch('/:userId/student')
updateStudent (
@Param('userId', UserByIdPipe) userId: string,
@Body() body: UpdateStudentDTO,
) {
return this.userService.updateStudent(userId, body);
}Example with guards
@ApiEndpoint({
summary: 'Give role to student',
guards: TelegramGuard,
})
@Post('/:userId/roles')
giveRole (
@Param('userId', UserByIdPipe) userId: string,
@Body() { roleId }: GiveRoleDTO,
) {
return this.userService.giveRole(userId, roleId);
}Our style has strict rules for placing decorators in controllers (I strongly recommend you to follow these theses)
- Your controller should start with
@ApiTags(tagName: string)with@Controller+ exporting class. - Then you are describing particular endpoint. The first decorator in your endpoint should be
Auth decorator, for instance,@ApiBearerAuth()or@ApiBasicAuth(). - After that, you should add
@ApiOkResponse({ type: ...Response }), where...Responseis our response. - Afterwards, you should add
@ApiBadRequestResponse()+@ApiUnauthorizedResponse+@ApiForbiddenResponsewith error description (Nota Bene you MUST use our error description style). - Subsequently, you should add custom
@ApiEndpoint()with summary and permission or guard (if it's required). - Eventually, you should add decorator that defines a route that handles HTTP method (e.g.
@Post).
Firstly, you should understand what type of error you are describing. For example, in @ApiUnauthorizedResponse() you should add this description :
description: `\n
UnauthorizedException:
Unauthorized`,
If you describe @ApiBadRequestResponse(), thus you need to look at services and dtos. When you describe your custom error, you
should follow these rules:
- Your error should be short without using unnecessary words.
- Your error should be informative.
- You should use templates e.g.
Discipline id cannot be empty;Discipline type must be an enum;Contact with such name is not foundetc...

When you describe fields, for example, in dtos, you should use appropriate words, tell the essence of this field, but not to repeat the name of the field. Example:
-
You have ForgotPasswordDTO with
emailfield. You should understand when, why and where this field is used.-
Wrong description:
Email of the user; -
Great description:
Email address of the user for whom you want to initiate the password reset procedure.
-
Wrong description:
-
You have
resetPasswordendpoint withtokenparam.-
Wrong description:
A reset token; -
Great description:
A password reset token that is generated and sent to the user's email address.
-
Wrong description:
When you describe default values in dtos, you should follow the database (if the database has default value, also NULL). Thus, you should add the default value from the database to your dto. Nota bene this value MUST be optional. For instance, you have QuerySemesterDTO with year? and semester? fields. In the database they have default value NULL => you should add in @ApiPropertyOptional() default: null, both for year? and semester?
When you describe default values in responses, you should use @ApiProperty(), not @ApiPropertyOptional(). If the field is optional => it is default in response. For example, you have CaptainResponse with optional field telegramId? => you should add in @ApiProperty() default: null, for telegramId?