Każdy dokument w cesarskiej kancelarii musiał mieć precyzyjnie opisane pola - imię petenta, rodzaj sprawy, datę i pieczęć. W NestJS odpowiednikiem tych dokumentów są DTO (Data Transfer Objects), a dekorator
@ApiProperty() opisuje każde pole tak, aby Swagger UI mógł je wyświetlić.Dekorator
@ApiProperty() opisuje pojedyncze pole w klasie DTO:1import { ApiProperty } from '@nestjs/swagger';
2
3export class CreateLegionaryDto {
4 @ApiProperty({
5 description: 'Imię legionisty',
6 example: 'Marcus Aurelius',
7 })
8 name: string;
9
10 @ApiProperty({
11 description: 'Ranga w legionie',
12 example: 'Centurio',
13 })
14 rank: string;
15
16 @ApiProperty({
17 description: 'Lata doświadczenia',
18 example: 5,
19 minimum: 0,
20 maximum: 40,
21 })
22 experience: number;
23}Dekorator przyjmuje wiele opcji konfiguracyjnych:
| Opcja | Opis | Przykład | |-------|------|---------| |
description | Opis pola | 'Imię legionisty' |
| example | Przykładowa wartość | 'Marcus' |
| required | Czy pole jest wymagane | true / false |
| default | Wartość domyślna | 'Miles' |
| enum | Lista dozwolonych wartości | ['Centurio', 'Miles'] |
| type | Typ pola | String, Number, Boolean |
| isArray | Czy pole jest tablicą | true |
| minimum | Minimalna wartość (number) | 0 |
| maximum | Maksymalna wartość (number) | 100 |
| minLength | Minimalna długość (string) | 2 |
| maxLength | Maksymalna długość (string) | 50 |Dla pól opcjonalnych używamy
@ApiPropertyOptional():1import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
3export class UpdateLegionaryDto {
4 @ApiPropertyOptional({
5 description: 'Nowa ranga legionisty',
6 example: 'Optio',
7 })
8 rank?: string;
9
10 @ApiPropertyOptional({
11 description: 'Nowy legion przypisania',
12 example: 'Legio III Augusta',
13 })
14 legio?: string;
15
16 @ApiPropertyOptional({
17 description: 'Dodatkowe doświadczenie',
18 example: 2,
19 minimum: 0,
20 })
21 additionalExperience?: number;
22}Enum jest szczególnie przydatny do pól z ograniczonym zestawem wartości:
1export enum LegionaryRank {
2 MILES = 'Miles',
3 OPTIO = 'Optio',
4 CENTURIO = 'Centurio',
5 TRIBUNUS = 'Tribunus',
6 LEGATUS = 'Legatus',
7}
8
9export class CreateLegionaryDto {
10 @ApiProperty({
11 description: 'Ranga legionisty',
12 enum: LegionaryRank,
13 example: LegionaryRank.MILES,
14 })
15 rank: LegionaryRank;
16}Dla zagnieżdżonych DTO używamy opcji
type:1export class AddressDto {
2 @ApiProperty({ description: 'Nazwa prowincji', example: 'Pannonia' })
3 province: string;
4
5 @ApiProperty({ description: 'Nazwa miasta', example: 'Aquincum' })
6 city: string;
7}
8
9export class LegionDto {
10 @ApiProperty({ description: 'Nazwa legionu', example: 'Legio X Gemina' })
11 name: string;
12
13 @ApiProperty({
14 description: 'Lokalizacja legionu',
15 type: AddressDto,
16 })
17 location: AddressDto;
18
19 @ApiProperty({
20 description: 'Lista centurionów',
21 type: [String],
22 example: ['Marcus', 'Julius', 'Gaius'],
23 })
24 centurions: string[];
25}Warto tworzyć osobne DTO dla odpowiedzi API:
1export class LegionaryResponseDto {
2 @ApiProperty({ description: 'ID legionisty', example: '507f1f77bcf86cd799439011' })
3 id: string;
4
5 @ApiProperty({ description: 'Imię legionisty', example: 'Marcus Aurelius' })
6 name: string;
7
8 @ApiProperty({ description: 'Ranga', enum: LegionaryRank })
9 rank: LegionaryRank;
10
11 @ApiProperty({ description: 'Data rekrutacji', example: '2024-01-15T10:30:00Z' })
12 recruitedAt: Date;
13
14 @ApiProperty({ description: 'Czy aktywny', example: true })
15 isActive: boolean;
16}Stwórz dokumentację DTO dla systemu zarządzania prowincjami Imperium: