OpenAPI7 min read

Kirish

OpenAPI spetsifikatsiyasi RESTful APIlarni tasvirlash uchun qo'llaniladigan tilga bog'liq bo'lmagan ta'rif formatidir. Nest dekoratorlardan foydalanib shunday spetsifikatsiyani yar

OpenAPI spetsifikatsiyasi RESTful APIlarni tasvirlash uchun qo'llaniladigan tilga bog'liq bo'lmagan ta'rif formatidir. Nest dekoratorlardan foydalanib shunday spetsifikatsiyani yaratishga imkon beradigan maxsus modulni taqdim etadi.

O'rnatish

Uni ishlata boshlash uchun avval kerakli qaramlikni o'rnatamiz.

Terminal
1$ npm install --save @nestjs/swagger

Dastlabki sozlash

O'rnatish yakunlangach, main.ts faylini oching va SwaggerModule klassi yordamida Swaggerni ishga tushiring:

TypeScript
main
1import { NestFactory } from '@nestjs/core';
2import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
3import { AppModule } from './app.module';
4
5async function bootstrap() {
6  const app = await NestFactory.create(AppModule);
7
8  const config = new DocumentBuilder()
9    .setTitle('Cats example')
10    .setDescription('The cats API description')
11    .setVersion('1.0')
12    .addTag('cats')
13    .build();
14  const documentFactory = () => SwaggerModule.createDocument(app, config);
15  SwaggerModule.setup('api', app, documentFactory);
16
17  await app.listen(process.env.PORT ?? 3000);
18}
19bootstrap();
Hint

Fabrika metodi SwaggerModule.createDocument() Swagger hujjatini aynan so'ralganda generatsiya qilish uchun ishlatiladi. Bu yondashuv boshlang'ich vaqtni tejaydi va natijaviy hujjat OpenAPI Document spetsifikatsiyasiga mos keladigan serializatsiya qilinadigan obyekt bo'ladi. Hujjatni HTTP orqali berish o'rniga, uni JSON yoki YAML fayl sifatida saqlab, turli usullarda ishlatishingiz mumkin.

DocumentBuilder OpenAPI spetsifikatsiyasiga mos bazaviy hujjatni tuzishga yordam beradi. U sarlavha, tavsif, versiya kabi xususiyatlarni o'rnatish imkonini beruvchi bir nechta metodlarni taqdim etadi. To'liq hujjatni (barcha HTTP marshrutlari bilan) yaratish uchun SwaggerModule klassining createDocument() metodidan foydalanamiz. Bu metod ikkita argument qabul qiladi: ilova nusxasi va Swagger parametrlar obyekti. Bundan tashqari, uchinchi argument sifatida SwaggerDocumentOptions turidagi obyektni berishimiz mumkin. Bu haqda ko'proq Hujjat parametrlar bo'limida yozilgan.

Hujjat yaratganimizdan so'ng, setup() metodini chaqirishimiz mumkin. U quyidagilarni qabul qiladi:

  1. Swagger UI joylashtiriladigan yo'l
  2. Ilova nusxasi
  3. Yuqorida yaratilgan hujjat obyekti
  4. Ixtiyoriy konfiguratsiya parametri (batafsil bu yerda)

Endi HTTP serverni ishga tushirish uchun quyidagi buyruqni bajaring:

Terminal
1$ npm run start

Ilova ishlayotgan vaqtda brauzerni ochib, http://localhost:3000/api manziliga o'ting. Swagger UI ko'rinadi.

Ko'rib turganingizdek, SwaggerModule endpointlaringizni avtomatik aks ettiradi.

Hint

Swagger JSON faylini yaratish va yuklab olish uchun http://localhost:3000/api-json manziliga o'ting (Swagger hujjatlaringiz http://localhost:3000/api ostida mavjud deb faraz qilinadi). Uni faqat @nestjs/swagger paketidagi setup metodidan foydalanib, xohlagan marshrutda taqdim etish ham mumkin, masalan:

SwaggerModule.setup('swagger', app, documentFactory, { jsonDocumentUrl: 'swagger/json', });

Bu uni http://localhost:3000/swagger/json manzilida taqdim etadi

Warning

fastify va helmet ishlatilganda CSP bilan bog'liq muammo yuzaga kelishi mumkin, bu kolliziyani quyidagi kabi CSP ni sozlab hal qiling:

app.register(helmet, { contentSecurityPolicy: { directives: { defaultSrc: [`'self'`], styleSrc: [`'self'`, `'unsafe-inline'`], imgSrc: [`'self'`, 'data:', 'validator.swagger.io'], scriptSrc: [`'self'`, `https: 'unsafe-inline'`], }, }, }); // If you are not going to use CSP at all, you can use this: app.register(helmet, { contentSecurityPolicy: false, });

Hujjat parametrlar

Hujjat yaratishda kutubxona xulqini yanada nozik sozlash uchun qo'shimcha parametrlar berish mumkin. Bu parametrlar SwaggerDocumentOptions turida bo'lishi kerak va quyidagilardan iborat bo'lishi mumkin:

TypeScript
1export interface SwaggerDocumentOptions {
2  /**
3   * List of modules to include in the specification
4   */
5  include?: Function[];
6
7  /**
8   * Additional, extra models that should be inspected and included in the specification
9   */
10  extraModels?: Function[];
11
12  /**
13   * If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
14   */
15  ignoreGlobalPrefix?: boolean;
16
17  /**
18   * If `true`, swagger will also load routes from the modules imported by `include` modules
19   */
20  deepScanRoutes?: boolean;
21
22  /**
23   * Custom operationIdFactory that will be used to generate the `operationId`
24   * based on the `controllerKey`, `methodKey`, and version.
25   * @default () => controllerKey_methodKey_version
26   */
27  operationIdFactory?: OperationIdFactory;
28
29  /**
30   * Custom linkNameFactory that will be used to generate the name of links
31   * in the `links` field of responses
32   *
33   * @see [Link objects](https://swagger.io/docs/specification/links/)
34   *
35   * @default () => `${controllerKey}_${methodKey}_from_${fieldKey}`
36   */
37  linkNameFactory?: (
38    controllerKey: string,
39    methodKey: string,
40    fieldKey: string
41  ) => string;
42
43  /*
44   * Generate tags automatically based on the controller name.
45   * If `false`, you must use the `@ApiTags()` decorator to define tags.
46   * Otherwise, the controller name without the suffix `Controller` will be used.
47   * @default true
48   */
49  autoTagControllers?: boolean;
50}

Masalan, kutubxona UsersController_createUser o'rniga createUser kabi operatsiya nomlarini generatsiya qilishiga ishonch hosil qilmoqchi bo'lsangiz, quyidagicha sozlash mumkin:

TypeScript
1const options: SwaggerDocumentOptions =  {
2  operationIdFactory: (
3    controllerKey: string,
4    methodKey: string
5  ) => methodKey
6};
7const documentFactory = () => SwaggerModule.createDocument(app, config, options);

Setup parametrlari

SwaggerModule#setup metodining to'rtinchi argumenti sifatida SwaggerCustomOptions interfeysiga mos keluvchi parametrlar obyektini uzatib, Swagger UI ni sozlashingiz mumkin.

TypeScript
1export interface SwaggerCustomOptions {
2  /**
3   * If `true`, Swagger resources paths will be prefixed by the global prefix set through `setGlobalPrefix()`.
4   * Default: `false`.
5   * @see https://docs.nestjs.com/faq/global-prefix
6   */
7  useGlobalPrefix?: boolean;
8
9  /**
10   * If `false`, the Swagger UI will not be served. Only API definitions (JSON and YAML)
11   * will be accessible (on `/{path}-json` and `/{path}-yaml`). To fully disable both the Swagger UI and API definitions, use `raw: false`.
12   * Default: `true`.
13   * @deprecated Use `ui` instead.
14   */
15  swaggerUiEnabled?: boolean;
16
17  /**
18   * If `false`, the Swagger UI will not be served. Only API definitions (JSON and YAML)
19   * will be accessible (on `/{path}-json` and `/{path}-yaml`). To fully disable both the Swagger UI and API definitions, use `raw: false`.
20   * Default: `true`.
21   */
22  ui?: boolean;
23
24  /**
25   * If `true`, raw definitions for all formats will be served.
26   * Alternatively, you can pass an array to specify the formats to be served, e.g., `raw: ['json']` to serve only JSON definitions.
27   * If omitted or set to an empty array, no definitions (JSON or YAML) will be served.
28   * Use this option to control the availability of Swagger-related endpoints.
29   * Default: `true`.
30   */
31  raw?: boolean | Array<'json' | 'yaml'>;
32
33  /**
34   * Url point the API definition to load in Swagger UI.
35   */
36  swaggerUrl?: string;
37
38  /**
39   * Path of the JSON API definition to serve.
40   * Default: `<path>-json`.
41   */
42  jsonDocumentUrl?: string;
43
44  /**
45   * Path of the YAML API definition to serve.
46   * Default: `<path>-yaml`.
47   */
48  yamlDocumentUrl?: string;
49
50  /**
51   * Hook allowing to alter the OpenAPI document before being served.
52   * It's called after the document is generated and before it is served as JSON & YAML.
53   */
54  patchDocumentOnRequest?: <TRequest = any, TResponse = any>(
55    req: TRequest,
56    res: TResponse,
57    document: OpenAPIObject
58  ) => OpenAPIObject;
59
60  /**
61   * If `true`, the selector of OpenAPI definitions is displayed in the Swagger UI interface.
62   * Default: `false`.
63   */
64  explorer?: boolean;
65
66  /**
67   * Additional Swagger UI options
68   */
69  swaggerOptions?: SwaggerUiOptions;
70
71  /**
72   * Custom CSS styles to inject in Swagger UI page.
73   */
74  customCss?: string;
75
76  /**
77   * URL(s) of a custom CSS stylesheet to load in Swagger UI page.
78   */
79  customCssUrl?: string | string[];
80
81  /**
82   * URL(s) of custom JavaScript files to load in Swagger UI page.
83   */
84  customJs?: string | string[];
85
86  /**
87   * Custom JavaScript scripts to load in Swagger UI page.
88   */
89  customJsStr?: string | string[];
90
91  /**
92   * Custom favicon for Swagger UI page.
93   */
94  customfavIcon?: string;
95
96  /**
97   * Custom title for Swagger UI page.
98   */
99  customSiteTitle?: string;
100
101  /**
102   * File system path (ex: ./node_modules/swagger-ui-dist) containing static Swagger UI assets.
103   */
104  customSwaggerUiPath?: string;
105
106  /**
107   * @deprecated This property has no effect.
108   */
109  validatorUrl?: string;
110
111  /**
112   * @deprecated This property has no effect.
113   */
114  url?: string;
115
116  /**
117   * @deprecated This property has no effect.
118   */
119  urls?: Record<'url' | 'name', string>[];
120}
Hint

ui va raw mustaqil parametrlar. Swagger UI (ui: false) ni o'chirish API ta'riflarini (JSON/YAML) o'chirmaydi. Aksincha, API ta'riflarini (raw: []) o'chirish Swagger UI ni o'chirmaydi.

Masalan, quyidagi konfiguratsiya Swagger UI ni o'chiradi, lekin API ta'riflariga kirish imkonini qoldiradi:

const options: SwaggerCustomOptions = { ui: false, // Swagger UI is disabled raw: ['json'], // JSON API definition is still accessible (YAML is disabled) }; SwaggerModule.setup('api', app, options);

Bu holda http://localhost:3000/api-json hali ham ochiq bo'ladi, lekin http://localhost:3000/api (Swagger UI) emas.

Misol

Ishlaydigan misol bu yerda mavjud.