OpenAPI6 min read

Turlar va parametrlari

SwaggerModule API hujjatini generatsiya qilish uchun marshrut handlerlaridagi barcha @Body(), @Query() va @Param() dekoratorlarini qidiradi. Shuningdek, reflectiondan foydalanib mo

SwaggerModule API hujjatini generatsiya qilish uchun marshrut handlerlaridagi barcha @Body(), @Query() va @Param() dekoratorlarini qidiradi. Shuningdek, reflectiondan foydalanib mos model ta'riflarini yaratadi. Quyidagi kodni ko'rib chiqing:

TypeScript
1@Post()
2async create(@Body() createCatDto: CreateCatDto) {
3  this.catsService.create(createCatDto);
4}
Hint

Body ta'rifini aniq belgilash uchun @ApiBody() dekoratoridan foydalaning (@nestjs/swagger paketidan import qilinadi).

CreateCatDto ga asoslanib Swagger UI uchun quyidagi model ta'rifi yaratiladi:

Ko'rib turganingizdek, klassda bir nechta xususiyatlar e'lon qilingan bo'lsa-da, ta'rif bo'sh. Klass xususiyatlarini SwaggerModule ga ko'rinarli qilish uchun ularni @ApiProperty() dekoratori bilan belgilashimiz yoki buni avtomatik bajaradigan CLI plaginidan foydalanishimiz kerak (batafsil Plagin bo'limida).

TypeScript
1import { ApiProperty } from '@nestjs/swagger';
2
3export class CreateCatDto {
4  @ApiProperty()
5  name: string;
6
7  @ApiProperty()
8  age: number;
9
10  @ApiProperty()
11  breed: string;
12}
Hint

Har bir xususiyatni qo'lda belgilash o'rniga, Swagger plaginidan foydalanishni o'ylab ko'ring (Plagin bo'limiga qarang), u buni avtomatik ta'minlaydi.

Brauzerni ochib, generatsiya qilingan CreateCatDto modelini tekshirib ko'ramiz:

Bundan tashqari, @ApiProperty() dekoratori turli Schema Object xususiyatlarini o'rnatish imkonini beradi:

TypeScript
1@ApiProperty({
2  description: 'The age of a cat',
3  minimum: 1,
4  default: 1,
5})
6age: number;
Hint

{{"@ApiProperty({ required: false })"}} ni qo'lda yozish o'rniga @ApiPropertyOptional() qisqa dekoratoridan foydalanishingiz mumkin.

Xususiyat turini aniq belgilash uchun type kalitidan foydalaning:

TypeScript
1@ApiProperty({
2  type: Number,
3})
4age: number;

Massivlar

Xususiyat massiv bo'lsa, quyidagi kabi massiv turini qo'lda ko'rsatishimiz kerak:

TypeScript
1@ApiProperty({ type: [String] })
2names: string[];
Hint

Massivlarni avtomatik aniqlaydigan Swagger plaginidan foydalanishni o'ylab ko'ring (Plagin bo'limiga qarang).

Yoki turini massivning birinchi elementi sifatida ko'rsating (yuqorida ko'rsatilganidek), yoki isArray xususiyatini true ga o'rnating.

Doiraviy qaramliklar

Klasslar o'rtasida doiraviy qaramliklar bo'lsa, SwaggerModule ga tur ma'lumotini taqdim etish uchun kechikkan funksiyadan foydalaning:

TypeScript
1@ApiProperty({ type: () => Node })
2node: Node;
Hint

Doiraviy qaramliklarni avtomatik aniqlaydigan Swagger plaginidan foydalanishni o'ylab ko'ring (Plagin bo'limiga qarang).

Generiklar va interfeyslar

TypeScript generiklar yoki interfeyslar haqidagi metadata ni saqlamaganligi sababli, ularni DTOlarda ishlatsangiz, SwaggerModule ish vaqtida model ta'riflarini to'g'ri generatsiya qila olmasligi mumkin. Masalan, quyidagi kod Swagger modul tomonidan to'g'ri tekshirilmaydi:

TypeScript
1createBulk(@Body() usersDto: CreateUserDto[])

Bu cheklovni chetlab o'tish uchun turini aniq belgilashingiz mumkin:

TypeScript
1@ApiBody({ type: [CreateUserDto] })
2createBulk(@Body() usersDto: CreateUserDto[])

Enumlar

enum ni aniqlash uchun @ApiProperty da enum xususiyatini qiymatlar massiviga qo'lda o'rnatishimiz kerak.

TypeScript
1@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
2role: UserRole;

Boshqa variant sifatida haqiqiy TypeScript enumini quyidagicha aniqlang:

TypeScript
1export enum UserRole {
2  Admin = 'Admin',
3  Moderator = 'Moderator',
4  User = 'User',
5}

Keyin enumni @ApiQuery() dekoratori bilan birgalikda @Query() parametr dekoratori bilan bevosita ishlatishingiz mumkin.

TypeScript
1@ApiQuery({ name: 'role', enum: UserRole })
2async filterByRole(@Query('role') role: UserRole = UserRole.User) {}

isArray true bo'lsa, enum ni multi-select sifatida tanlash mumkin:

Enumlar sxemasi

Standart holatda, enum xususiyati parameter ga Enum ning xom ta'rifini qo'shadi.

YAML
1- breed:
2    type: 'string'
3    enum:
4      - Persian
5      - Tabby
6      - Siamese

Yuqoridagi spetsifikatsiya ko'p hollarda yaxshi ishlaydi. Biroq, spetsifikatsiyani input sifatida olib, client-side kodni generatsiya qiluvchi vositadan foydalansangiz, yaratilgan kodda takroriy enum lar paydo bo'lishi muammosiga duch kelishingiz mumkin. Quyidagi kod parchasi buni ko'rsatadi:

TypeScript
1// generated client-side code
2export class CatDetail {
3  breed: CatDetailEnum;
4}
5
6export class CatInformation {
7  breed: CatInformationEnum;
8}
9
10export enum CatDetailEnum {
11  Persian = 'Persian',
12  Tabby = 'Tabby',
13  Siamese = 'Siamese',
14}
15
16export enum CatInformationEnum {
17  Persian = 'Persian',
18  Tabby = 'Tabby',
19  Siamese = 'Siamese',
20}
Hint

Yuqoridagi parcha NSwag deb nomlangan vosita yordamida generatsiya qilingan.

Ko'rib turganingizdek, endi bir xil bo'lgan ikki enum ga egasiz. Bu muammoni hal qilish uchun dekoratorda enum bilan birga enumName ni ham uzatishingiz mumkin.

TypeScript
1export class CatDetail {
2  @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
3  breed: CatBreed;
4}

enumName xususiyati @nestjs/swagger ga CatBreed ni alohida schema ga aylantirish imkonini beradi, bu esa CatBreed enumini qayta foydalanish mumkin qiladi. Spetsifikatsiya quyidagicha ko'rinadi:

YAML
1CatDetail:
2  type: 'object'
3  properties:
4    ...
5    - breed:
6        schema:
7          $ref: '#/components/schemas/CatBreed'
8CatBreed:
9  type: string
10  enum:
11    - Persian
12    - Tabby
13    - Siamese
Hint

enum xususiyatini qabul qiladigan har qanday dekoratorenumName ni ham qabul qiladi.

Xususiyat qiymatlari namunasi

example kalitidan foydalanib xususiyat uchun bitta namuna berishingiz mumkin:

TypeScript
1@ApiProperty({
2  example: 'persian',
3})
4breed: string;

Agar bir nechta namuna bermoqchi bo'lsangiz, quyidagi kabi obyektni uzatib examples kalitidan foydalanishingiz mumkin:

TypeScript
1@ApiProperty({
2  examples: {
3    Persian: { value: 'persian' },
4    Tabby: { value: 'tabby' },
5    Siamese: { value: 'siamese' },
6    'Scottish Fold': { value: 'scottish_fold' },
7  },
8})
9breed: string;

Xom ta'riflar

Ba'zi hollarda, masalan, chuqur qo'shama massivlar yoki matritsalar uchun turini qo'lda belgilashingiz kerak bo'lishi mumkin:

TypeScript
1@ApiProperty({
2  type: 'array',
3  items: {
4    type: 'array',
5    items: {
6      type: 'number',
7    },
8  },
9})
10coords: number[][];

Shuningdek, xom obyekt sxemalarini quyidagicha ko'rsatishingiz mumkin:

TypeScript
1@ApiProperty({
2  type: 'object',
3  properties: {
4    name: {
5      type: 'string',
6      example: 'Error'
7    },
8    status: {
9      type: 'number',
10      example: 400
11    }
12  },
13  required: ['name', 'status']
14})
15rawDefinition: Record<string, any>;

Controller klasslarida kirish/chiqish tarkibini qo'lda belgilash uchun schema xususiyatidan foydalaning:

TypeScript
1@ApiBody({
2  schema: {
3    type: 'array',
4    items: {
5      type: 'array',
6      items: {
7        type: 'number',
8      },
9    },
10  },
11})
12async create(@Body() coords: number[][]) {}

Qo'shimcha modellari

Controllerlaringizda to'g'ridan-to'g'ri ishlatilmaydigan, lekin Swagger modul tomonidan tekshirilishi kerak bo'lgan qo'shimcha modellarga ega bo'lish uchun @ApiExtraModels() dekoratoridan foydalaning:

TypeScript
1@ApiExtraModels(ExtraModel)
2export class CreateCatDto {}
Hint

Ma'lum model klassi uchun @ApiExtraModels() ni faqat bir marta ishlatishingiz kifoya.

Yoki SwaggerModule.createDocument() metodiga extraModels xususiyati ko'rsatilgan parametrlar obyektini quyidagicha uzatishingiz mumkin:

TypeScript
1const documentFactory = () =>
2  SwaggerModule.createDocument(app, options, {
3    extraModels: [ExtraModel],
4  });

Modelingizga havola ($ref) olish uchun getSchemaPath(ExtraModel) funksiyasidan foydalaning:

TypeScript
1'application/vnd.api+json': {
2   schema: { $ref: getSchemaPath(ExtraModel) },
3},

oneOf, anyOf, allOf

Sxemalarni birlashtirish uchun oneOf, anyOf yoki allOf kalit so'zlaridan foydalanishingiz mumkin (batafsil).

TypeScript
1@ApiProperty({
2  oneOf: [
3    { $ref: getSchemaPath(Cat) },
4    { $ref: getSchemaPath(Dog) },
5  ],
6})
7pet: Cat | Dog;

Agar polimorf massiv (ya'ni elementlari bir nechta sxemalarni qamrab oladigan massiv) aniqlamoqchi bo'lsangiz, turini qo'lda belgilash uchun xom ta'rifdan foydalanishingiz kerak (yuqoriga qarang).

TypeScript
1type Pet = Cat | Dog;
2
3@ApiProperty({
4  type: 'array',
5  items: {
6    oneOf: [
7      { $ref: getSchemaPath(Cat) },
8      { $ref: getSchemaPath(Dog) },
9    ],
10  },
11})
12pets: Pet[];
Hint

getSchemaPath() funksiyasi @nestjs/swagger dan import qilinadi.

Cat va Dog ning ikkalasi ham klass darajasida @ApiExtraModels() dekoratori yordamida qo'shimcha model sifatida aniqlanishi kerak.

Sxema nomi va tavsifi

Ehtimol payqagandirsiz, generatsiya qilingan sxema nomi original model klassi nomiga asoslanadi (masalan, CreateCatDto modeli CreateCatDto sxemasini generatsiya qiladi). Agar sxema nomini o'zgartirmoqchi bo'lsangiz, @ApiSchema() dekoratoridan foydalanishingiz mumkin.

Misol:

TypeScript
1@ApiSchema({ name: 'CreateCatRequest' })
2class CreateCatDto {}

Yuqoridagi model CreateCatRequest sxemasiga aylantiriladi.

Standart holatda generatsiya qilingan sxemaga tavsif qo'shilmaydi. description atributi orqali tavsif qo'shishingiz mumkin:

TypeScript
1@ApiSchema({ description: 'Description of the CreateCatDto schema' })
2class CreateCatDto {}

Shunday qilib, tavsif sxemaga quyidagicha kiritiladi:

YAML
1schemas:
2  CreateCatDto:
3    type: object
4    description: Description of the CreateCatDto schema