OpenAPI7 min read

CLI plagini

TypeScript metadata aks ettirish tizimi bir nechta cheklovlarga ega, masalan, klass qanday xususiyatlardan iboratligini yoki berilgan xususiyat majburiy yoki ixtiyoriy ekanini aniq

TypeScript metadata aks ettirish tizimi bir nechta cheklovlarga ega, masalan, klass qanday xususiyatlardan iboratligini yoki berilgan xususiyat majburiy yoki ixtiyoriy ekanini aniqlash qiyin. Biroq, bu cheklovlarning ayrimlarini kompilyatsiya vaqtida hal qilish mumkin. Nest boilerplate kod miqdorini kamaytirish uchun TypeScript kompilyatsiya jarayonini yaxshilovchi plagin taqdim etadi.

Hint

Bu plagin ixtiyoriy. Istasangiz, barcha dekoratorlarni qo'lda yoki kerak bo'lgan joylardagina deklaratsiya qilishingiz mumkin.

Umumiy ma'lumot

Swagger plagini avtomatik:

  • @ApiHideProperty qo'llanilmagan bo'lsa, barcha DTO xususiyatlarini @ApiProperty bilan belgilaydi
  • required xususiyatini so'roq belgisiga qarab o'rnatadi (masalan, name?: string required: false ni o'rnatadi)
  • type yoki enum xususiyatini turiga qarab o'rnatadi (massivlarni ham qo'llab-quvvatlaydi)
  • default xususiyatini berilgan standart qiymatga qarab o'rnatadi
  • class-validator dekoratorlariga asoslangan bir nechta tekshiruv qoidalarini o'rnatadi (classValidatorShim true bo'lsa)
  • har bir endpointga tegishli status va type (javob modeli) bilan javob dekoratorini qo'shadi
  • xususiyatlar va endpointlar uchun tavsiflarni kommentariyalarga asoslanib generatsiya qiladi (introspectComments true bo'lsa)
  • xususiyatlar uchun namuna qiymatlarni kommentariyalarga asoslanib generatsiya qiladi (introspectComments true bo'lsa)

E'tibor bering, fayl nomlaringiz plagin tomonidan tahlil qilinishi uchun albatta quyidagi suffikslardan biriga ega bo'lishi kerak: ['.dto.ts', '.entity.ts'] (masalan, create-user.dto.ts).

Agar boshqa suffiks ishlatayotgan bo'lsangiz, dtoFileNameSuffix parametrini ko'rsatib plagin xatti-harakatini moslashtirishingiz mumkin (quyida qarang).

Ilgari, Swagger UI bilan interaktiv tajriba taqdim etmoqchi bo'lsangiz, spetsifikatsiyada modellaringiz/komponentlaringiz qanday e'lon qilinishi kerakligini paketga bildirish uchun ko'p kodni takrorlashingiz kerak edi. Masalan, oddiy CreateUserDto klassini quyidagicha aniqlashingiz mumkin:

TypeScript
1export class CreateUserDto {
2  @ApiProperty()
3  email: string;
4
5  @ApiProperty()
6  password: string;
7
8  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
9  roles: RoleEnum[] = [];
10
11  @ApiProperty({ required: false, default: true })
12  isEnabled?: boolean = true;
13}

O'rta hajmdagi loyihalarda bu katta muammo bo'lmaydi, ammo ko'p sonli klasslar bilan ishlaganda kod ortiqcha va qo'llab-quvvatlash qiyin bo'lib qoladi.

Swagger plaginini yoqish orqali yuqoridagi klass ta'rifini soddaroq ko'rinishda yozish mumkin:

TypeScript
1export class CreateUserDto {
2  email: string;
3  password: string;
4  roles: RoleEnum[] = [];
5  isEnabled?: boolean = true;
6}
Note

Swagger plagini @ApiProperty() annotatsiyalarini TypeScript turlari va class-validator dekoratorlaridan oladi. Bu generatsiya qilingan Swagger UI hujjatlari uchun API ni aniq tasvirlashga yordam beradi. Biroq, ish vaqtida tekshiruv baribir class-validator dekoratorlari orqali bajariladi. Shuning uchun IsEmail(), IsNumber() kabi validatorlardan foydalanishda davom etish kerak.

Shunday qilib, hujjatlarni avtomatik annotatsiyalarga tayangan holda yaratmoqchi bo'lsangiz va ish vaqtida ham tekshiruvlarni xohlasangiz, class-validator dekoratorlari hali ham zarur.

Hint

DTOlarda mapped types utilities (masalan, PartialType) ishlatganda ularni sxemani plagin ushlashi uchun @nestjs/mapped-types o'rniga @nestjs/swagger dan import qiling.

Plagin Abstract Syntax Tree asosida kerakli dekoratorlarni darhol qo'shadi. Shunday qilib, kod bo'ylab tarqalgan @ApiProperty dekoratorlari bilan qiynalmaysiz.

Hint

Plagin yetishmayotgan swagger xususiyatlarini avtomatik generatsiya qiladi, lekin ularni almashtirishingiz kerak bo'lsa, @ApiProperty() orqali aniq ko'rsatib qo'yishingiz kifoya.

Kommentariyalarni tahlil qilish

Kommentariyalarni tahlil qilish funksiyasi yoqilganda, CLI plagini xususiyatlar uchun tavsiflar va namuna qiymatlarni kommentariyalarga asoslanib generatsiya qiladi.

Masalan, roles xususiyati misolida:

TypeScript
1/**
2 * A list of user's roles
3 * @example ['admin']
4 */
5@ApiProperty({
6  description: `A list of user's roles`,
7  example: ['admin'],
8})
9roles: RoleEnum[] = [];

Siz tavsif va namuna qiymatlarni ikkita joyda takrorlashingiz kerak. introspectComments yoqilganda, CLI plagini bu kommentariyalarni ajratib olib, xususiyatlar uchun tavsiflarni (va agar berilgan bo'lsa, namuna qiymatlarni) avtomatik taqdim etadi. Endi yuqoridagi xususiyatni quyidagicha sodda ko'rinishda yozish mumkin:

TypeScript
1/**
2 * A list of user's roles
3 * @example ['admin']
4 */
5roles: RoleEnum[] = [];

Plagin dtoKeyOfComment va controllerKeyOfComment parametrlarini taqdim etadi, ular mos ravishda ApiProperty va ApiOperation dekoratorlariga qiymatlar qanday berilishini sozlash imkonini beradi. Quyidagi misolga qarang:

TypeScript
1export class SomeController {
2  /**
3   * Create some resource
4   */
5  @Post()
6  create() {}
7}

Bu quyidagi ko'rsatmaga teng:

TypeScript
1@ApiOperation({ summary: "Create some resource" })
Hint

Modellar uchun ham xuddi shu mantiq qo'llaniladi, faqat ApiProperty dekoratori bilan.

Controllerlar uchun nafaqat qisqa mazmun, balki tavsif (izohlar), teglar (masalan, @deprecated) va javob namunalarini ham quyidagicha ko'rsatishingiz mumkin:

TypeScript
1/**
2 * Create a new cat
3 *
4 * @remarks This operation allows you to create a new cat.
5 *
6 * @deprecated
7 * @throws {500} Something went wrong.
8 * @throws {400} Bad Request.
9 */
10@Post()
11async create(): Promise<Cat> {}

CLI plagindan foydalanish

Plaginni yoqish uchun nest-cli.json (agar Nest CLI ishlatayotgan bo'lsangiz) faylini ochib, quyidagi plugins konfiguratsiyasini qo'shing:

JavaScript
1{
2  "collection": "@nestjs/schematics",
3  "sourceRoot": "src",
4  "compilerOptions": {
5    "plugins": ["@nestjs/swagger"]
6  }
7}

Plagin xatti-harakatini moslashtirish uchun options xususiyatidan foydalanishingiz mumkin.

JavaScript
1{
2  "collection": "@nestjs/schematics",
3  "sourceRoot": "src",
4  "compilerOptions": {
5    "plugins": [
6      {
7        "name": "@nestjs/swagger",
8        "options": {
9          "classValidatorShim": false,
10          "introspectComments": true,
11          "skipAutoHttpCode": true
12        }
13      }
14    ]
15  }
16}

options xususiyati quyidagi interfeysga mos bo'lishi kerak:

TypeScript
1export interface PluginOptions {
2  dtoFileNameSuffix?: string[];
3  controllerFileNameSuffix?: string[];
4  classValidatorShim?: boolean;
5  dtoKeyOfComment?: string;
6  controllerKeyOfComment?: string;
7  introspectComments?: boolean;
8  skipAutoHttpCode?: boolean;
9  esmCompatible?: boolean;
10}
ParametrStandartTavsif
dtoFileNameSuffix['.dto.ts', '.entity.ts']DTO (Data Transfer Object) fayllar suffiksi
controllerFileNameSuffix.controller.tsController fayllar suffiksi
classValidatorShimtrueAgar true bo'lsa, modul class-validator tekshiruv dekoratorlaridan qayta foydalanadi (masalan, @Max(10) sxema ta'rifiga max: 10 ni qo'shadi)
dtoKeyOfComment'description'ApiProperty da kommentariya matnini o'rnatish uchun ishlatiladigan xususiyat kaliti.
controllerKeyOfComment'summary'ApiOperation da kommentariya matnini o'rnatish uchun ishlatiladigan xususiyat kaliti.
introspectCommentsfalseAgar true bo'lsa, plagin kommentariyalarga asoslanib xususiyatlar uchun tavsif va namuna qiymatlarni generatsiya qiladi
skipAutoHttpCodefalseControllerlarda @HttpCode() ni avtomatik qo'shishni o'chiradi
esmCompatiblefalseAgar true bo'lsa, ESM ({ "type": "module" }) ishlatilganda yuzaga keladigan sintaksis xatolarini hal qiladi.

Plagin parametrlari yangilanganda /dist papkasini o'chirib, ilovangizni qayta build qiling. Agar CLI dan foydalanmasangiz va maxsus webpack konfiguratsiyasiga ega bo'lsangiz, bu plaginini ts-loader bilan birgalikda ishlatishingiz mumkin:

JavaScript
1getCustomTransformers: (program: any) => ({
2  before: [require('@nestjs/swagger/plugin').before({}, program)]
3}),

SWC builder

Standart (monorepo bo'lmagan) sozlamalarda SWC builder bilan CLI plaginlarini ishlatish uchun bu yerda ko'rsatilganidek type checkingni yoqish kerak.

Terminal
1$ nest start -b swc --type-check

Monorepo sozlamalari uchun bu yerdagi ko'rsatmalarga amal qiling.

Terminal
1$ npx ts-node src/generate-metadata.ts
2# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts

Endi serializatsiya qilingan metadata fayli quyidagidek SwaggerModule#loadPluginMetadata metodi orqali yuklanishi kerak:

TypeScript
1import metadata from './metadata'; // <-- file auto-generated by the "PluginMetadataGenerator"
2
3await SwaggerModule.loadPluginMetadata(metadata); // <-- here
4const document = SwaggerModule.createDocument(app, config);

ts-jest bilan integratsiya (e2e testlar)

e2e testlarni ishlatish uchun ts-jest manba fayllaringizni xotirada, joyida kompilyatsiya qiladi. Demak, u Nest CLI kompilyatoridan foydalanmaydi va hech qanday plagin qo'llamaydi yoki AST transformatsiyalarini bajaradi.

Plaginni yoqish uchun e2e testlar katalogida quyidagi faylni yarating:

JavaScript
1const transformer = require('@nestjs/swagger/plugin');
2
3module.exports.name = 'nestjs-swagger-transformer';
4// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
5module.exports.version = 1;
6
7module.exports.factory = (cs) => {
8  return transformer.before(
9    {
10      // @nestjs/swagger/plugin options (can be empty)
11    },
12    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
13  );
14};

Bundan so'ng, jest konfiguratsiya faylingizda AST transformerni import qiling. Standart holatda (starter ilovada) e2e testlar konfiguratsiyasi test papkasi ostida joylashgan va jest-e2e.json deb nomlanadi.

Agar jest@<29 ishlatsangiz, quyidagi parcha kodni qo'llang.

JSON
1{
2  ... // other configuration
3  "globals": {
4    "ts-jest": {
5      "astTransformers": {
6        "before": ["<path to the file created above>"]
7      }
8    }
9  }
10}

Agar jest@^29 ishlatsangiz, avvalgi yondashuv eskirganligi sababli quyidagi parcha kodni qo'llang.

JSON
1{
2  ... // other configuration
3  "transform": {
4    "^.+\\.(t|j)s$": [
5      "ts-jest",
6      {
7        "astTransformers": {
8          "before": ["<path to the file created above>"]
9        }
10      }
11    ]
12  }
13}

jest (e2e testlar) bilan muammolarni hal qilish

jest konfiguratsiya o'zgarishlarini ko'rmayotgandek bo'lsa, Jest allaqachon build natijasini keshlagan bo'lishi mumkin. Yangi konfiguratsiyani qo'llash uchun Jest kesh katalogini tozalash kerak.

Kesh katalogini tozalash uchun NestJS loyihangiz papkasida quyidagi buyruqni bajaring:

Terminal
1$ npx jest --clearCache

Agar keshni avtomatik tozalash muvaffaqiyatsiz bo'lsa, quyidagi buyruqlar bilan kesh papkasini qo'lda o'chirishingiz mumkin:

Terminal
1# Find jest cache directory (usually /tmp/jest_rs)
2# by running the following command in your NestJS project root
3$ npx jest --showConfig | grep cache
4# ex result:
5#   "cache": true,
6#   "cacheDirectory": "/tmp/jest_rs"
7
8# Remove or empty the Jest cache directory
9$ rm -rf  <cacheDirectory value>
10# ex:
11# rm -rf /tmp/jest_rs