Привет всем, на этот раз короткая статья.
Когда я начал использовать NestJs с Nx, я заметил один непредвиденный момент, до сих пор идут споры о том, как активировать OpenApi/Swagger в NestJs с опцией автоматической документации.
Больше не бойтесь, в конце этого руководства эта проблема будет решена.
Используемые версии
Я использую последнюю версию Nx на момент написания статьи, а именно V14, с NestJs 8.0 и NestJs Swagger 5.2.
Пакеты
Сначала установите необходимый пакет, если вы используете express, установите npm install --save @nestjs/swagger swagger-ui-express
в противном случае, для fastify используйте npm install --save @nestjs/swagger fastify-swagger
.
Добавьте модуль Swagger
В main.ts
из папки проекта NestJs добавьте следующее:
function setupOpenApi(app: INestApplication) {
const config = new DocumentBuilder().setTitle('API Documentation').setVersion('1.0').addTag('api').build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
}
затем в функции bootstrap
просто вызовите функцию setupOpenApi
.
Весь мой main.ts
выглядит следующим образом, обратите внимание, что я предпочел следующие варианты:
- Я использовал Fastify, потому что у меня нет жесткой зависимости от express middleware, и это улучшает производительность.
- Я использовал глобальный префикс, поэтому мне пришлось установить
useGlobalPrefix:true
в функции выше. - Глобальный префикс, который я использовал, по умолчанию
api
, что конфликтует с маршрутом по умолчанию для OpenApi, который в документации совпадает сapi
. Если вы оставите их в таком виде без добавления флагаuseGlobalPrefix: true
, то вы сможете получить доступ и к API, и к OpenAPI наhttp://localhost:3000/api
, но вы заметите, что документация неверна, поскольку в ней не указан используемыйglobalPrefix
. Чтобы исправить это, мы должны установить флагuseGlobalPrefix: true
для OpenAPI и получить доступ к документации по адресуhttp://localhost:3000/api/api
, что выглядит странно, поэтому я изменил его наhttp://localhost:3000/api/openApi
Пример работы ниже:
/**
* This is not a production server yet!
* This is only a minimal backend to get started.
*/
import { INestApplication, Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app/app.module';
async function bootstrap() {
const fastifyOptions: ConstructorParameters<typeof FastifyAdapter>[0] = {
logger: true,
};
const fastifyAdapter = new FastifyAdapter(fastifyOptions);
const app = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter);
const globalPrefix = 'api';
app.setGlobalPrefix(globalPrefix);
setupOpenApi(app);
const port = process.env.PORT || 3333;
await app.listen(port);
Logger.log(`🚀 Application is running on: http://localhost:${port}/${globalPrefix}`);
}
bootstrap();
function setupOpenApi(app: INestApplication) {
const config = new DocumentBuilder().setTitle('API Documentation').setVersion('1.0').addTag('api').build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('openApi', app, document, { useGlobalPrefix: true });
}
Сейчас вы готовы использовать часть пакета с ручной документацией, но мы оба знаем, что вы здесь не для этого.
Автоматическая документация
Это будет довольно коротко, у нас есть 2 не хакерских способа сделать это.
Nest-Cli.json — Не предлагается
Просто создайте файл nest-cli.json
в корне проекта, затем добавьте в него
{
"collection": "@nestjs/schematics",
"sourceRoot": "apps",
"compilerOptions": {
"plugins": [
{
"name": "@nestjs/swagger/plugin",
"options": {
"dtoFileNameSuffix": [".entity.ts", ".dto.ts"],
"controllerFileNameSuffix": [".controller.ts"],
"classValidatorShim": true,
"dtoKeyOfComment": "description",
"controllerKeyOfComment": "description",
"introspectComments": true
}
}
]
}
}
Не пугайтесь приведенных выше настроек, это просто настройки по умолчанию, чтобы быть более явными. Что действительно изменяется, так это sourceRoot
, который в случае с NX (по крайней мере, для пресетов с приложениями) является папкой apps
.
Это должно определить ваши параметры и имена классов, но, скорее всего, не увидит, что находится внутри ваших классов, и они будут казаться пустыми.
TsPlugin — рекомендуется, более настраиваемый
Перейдите к вашему project.json
в папке проекта NestJs или angular.json
в корневой папке для более старой версии и найдите нужный вам проект. Нам потребуется изменить команду build
.
Вся команда сборки показана ниже
"build": {
"executor": "@nrwl/node:webpack",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/api",
"main": "apps/api/src/main.ts",
"tsConfig": "apps/api/tsconfig.app.json",
"tsPlugins": [
{
"name": "@nestjs/swagger/plugin",
"options": {
"dtoFileNameSuffix": [".entity.ts", ".dto.ts"],
"controllerFileNameSuffix": [".controller.ts"],
"classValidatorShim": true,
"dtoKeyOfComment": "description",
"controllerKeyOfComment": "description",
"introspectComments": true
}
}
],
"assets": ["apps/api/src/assets"]
},
Как вы можете заметить, мы добавили пользовательский Webpack TsPlugin, как указано в документации над этим https://docs.nestjs.com/openapi/cli-plugin#integration-with-ts-jest-e2e-tests.
Как уже упоминалось, это рекомендуемый подход, он будет видеть все классы из любого места в монорепо, если они импортированы в проект.
Последние детали
Помните следующее:
- Вы можете использовать только
class
es, а неinterface
es. - Вам необходимо добавить
.dto.ts
или.entity.ts
, если вы не измените это.
Спасибо за прочтение!