Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Dekoratory kontrolerów - pieczęcie na dekretach

Każdy dekret cesarski w Imperium musiał być opatrzony odpowiednimi pieczęciami i oznaczeniami - kto go wydał, czego dotyczy i jakie są konsekwencje. W NestJS dekoratory Swagger pełnią dokładnie tę samą rolę - opisują nasze endpointy tak, aby każdy developer mógł je zrozumieć.

@ApiTags - Księgi Annałów

Dekorator

@ApiTags()
grupuje endpointy w logiczne sekcje. Tak jak annały Imperium dzieliły się na księgi (Lex Militaris, Lex Tributaria), tak nasze API dzieli się na tagi:

1import { Controller, Get, Post, Body, Param } from '@nestjs/common';
2import { ApiTags } from '@nestjs/swagger';
3
4@ApiTags('Legiones')
5@Controller('legiones')
6export class LegionController {
7  // Wszystkie endpointy tego kontrolera
8  // pojawią się w sekcji "Legiones" w Swagger UI
9}
10
11@ApiTags('Provinciae')
12@Controller('provinciae')
13export class ProvinceController {
14  // Te endpointy będą w sekcji "Provinciae"
15}

Możesz przypisać wiele tagów do jednego kontrolera:

1@ApiTags('Legiones', 'Military')
2@Controller('legiones')
3export class LegionController {}

@ApiOperation - Dekret Cesarski

@ApiOperation()
opisuje pojedynczy endpoint - co robi i w jakim celu:

1@ApiTags('Legiones')
2@Controller('legiones')
3export class LegionController {
4  @ApiOperation({
5    summary: 'Pobierz listę legionów',
6    description: 'Zwraca pełną listę wszystkich legionów Imperium wraz z ich lokalizacjami i liczbą żołnierzy.',
7  })
8  @Get()
9  findAll() {
10    return this.legionService.findAll();
11  }
12
13  @ApiOperation({
14    summary: 'Rekrutuj nowego legionistę',
15    description: 'Dodaje nowego żołnierza do wybranego legionu. Wymaga rangi i przypisania do kohorty.',
16  })
17  @Post()
18  recruit(@Body() dto: CreateLegionaryDto) {
19    return this.legionService.recruit(dto);
20  }
21}

@ApiResponse - Edykty odpowiedzi

@ApiResponse()
definiuje możliwe odpowiedzi endpointu - jakie kody statusu może zwrócić i co one oznaczają:

1import { ApiResponse } from '@nestjs/swagger';
2
3@ApiOperation({ summary: 'Znajdź legion po ID' })
4@ApiResponse({
5  status: 200,
6  description: 'Legion znaleziony',
7})
8@ApiResponse({
9  status: 404,
10  description: 'Legion nie istnieje',
11})
12@Get(':id')
13findOne(@Param('id') id: string) {
14  return this.legionService.findOne(id);
15}

@ApiParam - Parametry ścieżki

@ApiParam()
opisuje parametry w URL (route parameters):

1import { ApiParam } from '@nestjs/swagger';
2
3@ApiOperation({ summary: 'Pobierz legion po ID' })
4@ApiParam({
5  name: 'id',
6  description: 'Unikalny identyfikator legionu',
7  example: 'legio-x-gemina',
8  type: String,
9})
10@Get(':id')
11findOne(@Param('id') id: string) {
12  return this.legionService.findOne(id);
13}

@ApiQuery - Parametry zapytania

@ApiQuery()
opisuje query parameters (po znaku
?
w URL):

1import { ApiQuery } from '@nestjs/swagger';
2
3@ApiOperation({ summary: 'Wyszukaj legiony' })
4@ApiQuery({
5  name: 'province',
6  required: false,
7  description: 'Filtruj po prowincji',
8  example: 'Pannonia',
9})
10@ApiQuery({
11  name: 'minSoldiers',
12  required: false,
13  description: 'Minimalna liczba żołnierzy',
14  type: Number,
15})
16@Get('search')
17search(
18  @Query('province') province?: string,
19  @Query('minSoldiers') minSoldiers?: number,
20) {
21  return this.legionService.search(province, minSoldiers);
22}

@ApiBearerAuth - Signum Legionu

@ApiBearerAuth()
oznacza endpoint jako chroniony uwierzytelnieniem JWT:

1import { ApiBearerAuth } from '@nestjs/swagger';
2import { UseGuards } from '@nestjs/common';
3
4@ApiBearerAuth('JWT-auth')
5@UseGuards(JwtAuthGuard)
6@ApiOperation({ summary: 'Awansuj legionistę' })
7@Post(':id/promote')
8promote(@Param('id') id: string) {
9  return this.legionService.promote(id);
10}

Pełny przykład kontrolera z dekoratorami

1@ApiTags('Legiones')
2@Controller('legiones')
3export class LegionController {
4  constructor(private readonly legionService: LegionService) {}
5
6  @ApiOperation({ summary: 'Pobierz wszystkie legiony' })
7  @ApiResponse({ status: 200, description: 'Lista legionów' })
8  @Get()
9  findAll() {
10    return this.legionService.findAll();
11  }
12
13  @ApiOperation({ summary: 'Pobierz legion po ID' })
14  @ApiParam({ name: 'id', description: 'ID legionu' })
15  @ApiResponse({ status: 200, description: 'Legion znaleziony' })
16  @ApiResponse({ status: 404, description: 'Legion nie znaleziony' })
17  @Get(':id')
18  findOne(@Param('id') id: string) {
19    return this.legionService.findOne(id);
20  }
21
22  @ApiBearerAuth('JWT-auth')
23  @UseGuards(JwtAuthGuard)
24  @ApiOperation({ summary: 'Rekrutuj legionistę' })
25  @ApiResponse({ status: 201, description: 'Legionista zrekrutowany' })
26  @ApiResponse({ status: 401, description: 'Brak autoryzacji' })
27  @Post()
28  recruit(@Body() dto: CreateLegionaryDto) {
29    return this.legionService.recruit(dto);
30  }
31}

Ćwiczenie praktyczne

Dodaj dekoratory Swagger do kontrolera zarządzającego prowincjami Imperium:

Przejdź do CodeWorlds