In the imperial chancellery, every edict had to clearly define the consequences - what happens in case of success, what happens in case of a law violation, and what happens when the petitioner lacks authorization. In Swagger, we document this using specialized response decorators.
Instead of the generic
@ApiResponse(), NestJS Swagger offers dedicated decorators for each HTTP status code:1import {
2 ApiOkResponse,
3 ApiCreatedResponse,
4 ApiNotFoundResponse,
5 ApiBadRequestResponse,
6 ApiUnauthorizedResponse,
7 ApiForbiddenResponse,
8 ApiConflictResponse,
9 ApiInternalServerErrorResponse,
10} from '@nestjs/swagger';We use it when the endpoint returns data successfully:
1@ApiOkResponse({
2 description: 'List of Empire legions',
3 type: [LegionResponseDto],
4})
5@Get()
6findAll(): LegionResponseDto[] {
7 return this.legionService.findAll();
8}For endpoints creating new resources:
1@ApiCreatedResponse({
2 description: 'Legionary has been successfully recruited',
3 type: LegionaryResponseDto,
4})
5@Post()
6recruit(@Body() dto: CreateLegionaryDto): LegionaryResponseDto {
7 return this.legionService.recruit(dto);
8}When the requested resource does not exist:
1@ApiNotFoundResponse({
2 description: 'Legion with the given ID was not found in the annals of the Empire',
3})
4@Get(':id')
5findOne(@Param('id') id: string) {
6 return this.legionService.findOne(id);
7}When the input data is invalid:
1@ApiBadRequestResponse({
2 description: 'Invalid recruitment data - check the required fields',
3})
4@Post()
5recruit(@Body() dto: CreateLegionaryDto) {
6 return this.legionService.recruit(dto);
7}When the user is not authenticated:
1@ApiUnauthorizedResponse({
2 description: 'Missing valid JWT token - imperial seal required',
3})
4@ApiBearerAuth('JWT-auth')
5@UseGuards(JwtAuthGuard)
6@Delete(':id')
7dismiss(@Param('id') id: string) {
8 return this.legionService.dismiss(id);
9}In practice, each endpoint should document all possible responses:
1@ApiOperation({ summary: 'Promote a legionary' })
2@ApiOkResponse({
3 description: 'Legionary has been promoted',
4 type: LegionaryResponseDto,
5})
6@ApiNotFoundResponse({
7 description: 'Legionary not found',
8})
9@ApiUnauthorizedResponse({
10 description: 'Unauthorized - JWT token required',
11})
12@ApiBadRequestResponse({
13 description: 'Invalid target rank',
14})
15@ApiBearerAuth('JWT-auth')
16@UseGuards(JwtAuthGuard)
17@Patch(':id/promote')
18promote(
19 @Param('id') id: string,
20 @Body() dto: PromoteLegionaryDto,
21): LegionaryResponseDto {
22 return this.legionService.promote(id, dto);
23}The
type option in response decorators allows you to link the response to a specific DTO:1// Single object response
2@ApiOkResponse({ type: LegionResponseDto })
3
4// Array of objects response
5@ApiOkResponse({ type: [LegionResponseDto] })
6
7// Response with description
8@ApiOkResponse({
9 description: 'Legion details',
10 type: LegionResponseDto,
11})Thanks to this, Swagger UI will display the full response schema with example values.
Add advanced response decorators to the tribute controller of the Empire: