Добавление Swagger документации в NestJS-mod приложение и генерация REST-клиента для Angular-приложения
Подключение генератора Swagger документации к бэкенду.
Подклю чение https://www.npmjs.com/package/prisma-class-generator для генерации DTO из Prisma - схемы.
Создание nx библиотеки для работы с бэкендом.
Подключение https://www.npmjs.com/package/@openapitools/openapi-generator-cli для генерации SDK для работы с бэкендом.
1. Устанавливаем все необходимые пакеты
Команды
# Install all need dependencies
npm i --save @nestjs/swagger
# Install all need dev-dependencies
npm i --save-dev prisma-class-generator @openapitools/openapi-generator-cli
# Install all need peer-dependencies
npm i --save class-transformer class-validator
Вывод консоли
$ npm i --save @nestjs/swagger
added 5 packages, removed 1 package, and audited 2512 packages in 14s
300 packages are looking for funding
run `npm fund` for details
17 vulnerabilities (6 moderate, 11 high)
To address issues that do not require attention, run:
npm audit fix
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
$ npm i --save-dev prisma-class-generator @openapitools/openapi-generator-cli
added 50 packages, and audited 2562 packages in 15s
304 packages are looking for funding
run `npm fund` for details
18 vulnerabilities (6 moderate, 12 high)
To address issues that do not require attention, run:
npm audit fix
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
$ npm i --save class-transformer class-validator
added 1 package, removed 1 package, and audited 2768 packages in 9s
331 packages are looking for funding
run `npm fund` for details
18 vulnerabilities (6 moderate, 12 high)
To address issues that do not require attention, run:
npm audit fix
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
2. Создаем Angular библиотеку для работы с бэкендом
Эта библиотека будет использоваться для работы с бэкендом.
Команды
# Create Angular library
./node_modules/.bin/nx g @nx/angular:library app-angular-rest-sdk --buildable --publishable --directory=libs/sdk/app-angular-rest-sdk --simpleName=true --projectNameAndRootFormat=as-provided --strict=true --prefix=app-angular-rest-sdk --standalone=true --selector=app-angular-rest-sdk --changeDetection=OnPush --importPath=@nestjs-mod-fullstack/app-angular-rest-sdk
# Change file with test options
rm -rf libs/sdk/app-angular-rest-sdk/src/test-setup.ts
cp apps/client/src/test-setup.ts libs/sdk/app-angular-rest-sdk/src/test-setup.ts
Вывод консоли
$ ./node_modules/.bin/nx g @nx/angular:library app-angular-rest-sdk --buildable --publishable --directory=libs/sdk/app-angular-rest-sdk --simpleName=true --projectNameAndRootFormat=as-provided --strict=true --prefix=app-angular-rest-sdk --standalone=true --selector=app-angular-rest-sdk --changeDetection=OnPush --importPath=@nestjs-mod-fullstack/app-angular-rest-sdk
NX Generating @nx/angular:library
UPDATE nx.json
CREATE libs/sdk/app-angular-rest-sdk/project.json
CREATE libs/sdk/app-angular-rest-sdk/README.md
CREATE libs/sdk/app-angular-rest-sdk/ng-package.json
CREATE libs/sdk/app-angular-rest-sdk/package.json
CREATE libs/sdk/app-angular-rest-sdk/tsconfig.json
CREATE libs/sdk/app-angular-rest-sdk/tsconfig.lib.json
CREATE libs/sdk/app-angular-rest-sdk/tsconfig.lib.prod.json
CREATE libs/sdk/app-angular-rest-sdk/src/index.ts
CREATE libs/sdk/app-angular-rest-sdk/jest.config.ts
CREATE libs/sdk/app-angular-rest-sdk/src/test-setup.ts
CREATE libs/sdk/app-angular-rest-sdk/tsconfig.spec.json
CREATE libs/sdk/app-angular-rest-sdk/src/lib/app-angular-rest-sdk/app-angular-rest-sdk.component.css
CREATE libs/sdk/app-angular-rest-sdk/src/lib/app-angular-rest-sdk/app-angular-rest-sdk.component.html
CREATE libs/sdk/app-angular-rest-sdk/src/lib/app-angular-rest-sdk/app-angular-rest-sdk.component.spec.ts
CREATE libs/sdk/app-angular-rest-sdk/src/lib/app-angular-rest-sdk/app-angular-rest-sdk.component.ts
CREATE libs/sdk/app-angular-rest-sdk/.eslintrc.json
UPDATE package.json
UPDATE tsconfig.base.json
added 31 packages, removed 37 packages, and audited 2556 packages in 12s
304 packages are looking for funding
run `npm fund` for details
16 vulnerabilities (4 moderate, 12 high)
To address issues that do not require attention, run:
npm audit fix
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
NX 👀 View Details of app-angular-rest-sdk
Run "nx show project app-angular-rest-sdk" to view details about this project.
3. Создаем NestJS библиотеку для работы с бэкендом
Эта библиотека будет использоваться из E2E-тестов бэкенда.
Команды
# Create NestJS library
./node_modules/.bin/nx g @nestjs-mod/schematics:library app-rest-sdk --buildable --publishable --directory=libs/sdk/app-rest-sdk --simpleName=true --projectNameAndRootFormat=as-provided --strict=true
Вывод консоли
$ ./node_modules/.bin/nx g @nestjs-mod/schematics:library app-rest-sdk --buildable --publishable --directory=libs/sdk/app-rest-sdk --simpleName=true --projectNameAndRootFormat=as-provided --strict=true
NX Generating @nestjs-mod/schematics:library
CREATE libs/sdk/app-rest-sdk/tsconfig.json
CREATE libs/sdk/app-rest-sdk/src/index.ts
CREATE libs/sdk/app-rest-sdk/tsconfig.lib.json
CREATE libs/sdk/app-rest-sdk/README.md
CREATE libs/sdk/app-rest-sdk/package.json
CREATE libs/sdk/app-rest-sdk/project.json
CREATE libs/sdk/app-rest-sdk/.eslintrc.json
CREATE libs/sdk/app-rest-sdk/jest.config.ts
CREATE libs/sdk/app-rest-sdk/tsconfig.spec.json
UPDATE tsconfig.base.json
CREATE libs/sdk/app-rest-sdk/src/lib/app-rest-sdk.configuration.ts
CREATE libs/sdk/app-rest-sdk/src/lib/app-rest-sdk.environments.ts
CREATE libs/sdk/app-rest-sdk/src/lib/app-rest-sdk.module.ts
4. Добавляем дополнительный генератор DTO в Prisma-схему
Обновленный файл apps/server/src/prisma/app-schema.prisma
generator client {
provider = "prisma-client-js"
output = "../../../../node_modules/@prisma/app-client"
engineType = "binary"
}
generator prismaClassGenerator {
provider = "prisma-class-generator"
output = "../app/generated/rest/dto"
dryRun = "false"
separateRelationFields = "false"
makeIndexFile = "file"
}
datasource db {
provider = "postgres"
url = env("SERVER_APP_DATABASE_URL")
}
model AppDemo {
id String @id(map: "PK_APP_DEMO") @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
name String @unique(map: "UQ_APP_DEMO") @db.VarChar(128)
createdAt DateTime @default(now()) @db.Timestamp(6)
updatedAt DateTime @default(now()) @db.Timestamp(6)
}
model migrations {
installed_rank Int @id(map: "__migrations_pk")
version String? @db.VarChar(50)
description String @db.VarChar(200)
type String @db.VarChar(20)
script String @db.VarChar(1000)
checksum Int?
installed_by String @db.VarChar(100)
installed_on DateTime @default(now()) @db.Timestamp(6)
execution_time Int
success Boolean
@@index([success], map: "__migrations_s_idx")
@@map("__migrations")
}
5. Добавляем поддержку генерации Swagger документации в бэкенд коде
Обновленный файла apps/server/src/main.ts
import { DefaultNestApplicationInitializer, DefaultNestApplicationListener, InfrastructureMarkdownReportGenerator, PACKAGE_JSON_FILE, ProjectUtils, bootstrapNestApplication, isInfrastructureMode } from '@nestjs-mod/common';
import { DOCKER_COMPOSE_FILE, DockerCompose, DockerComposePostgreSQL } from '@nestjs-mod/docker-compose';
import { FLYWAY_JS_CONFIG_FILE, Flyway } from '@nestjs-mod/flyway';
import { NestjsPinoLoggerModule } from '@nestjs-mod/pino';
import { ECOSYSTEM_CONFIG_FILE, Pm2 } from '@nestjs-mod/pm2';
import { FakePrismaClient, PRISMA_SCHEMA_FILE, PrismaModule } from '@nestjs-mod/prisma';
import { TerminusHealthCheckModule } from '@nestjs-mod/terminus';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { MemoryHealthIndicator } from '@nestjs/terminus';
import { writeFileSync } from 'fs';
import { join, resolve } from 'path';
import { AppModule } from './app/app.module';
const appFeatureName = 'app';
const rootFolder = join(__dirname, '..', '..', '..');
const appFolder = join(rootFolder, 'apps', 'server');
bootstrapNestApplication({
modules: {
system: [
ProjectUtils.forRoot({
staticConfiguration: {
applicationPackageJsonFile: join(appFolder, PACKAGE_JSON_FILE),
packageJsonFile: join(rootFolder, PACKAGE_JSON_FILE),
envFile: join(rootFolder, '.env'),
},
}),
DefaultNestApplicationInitializer.forRoot({
staticConfiguration: { bufferLogs: true },
}),
NestjsPinoLoggerModule.forRoot(),
TerminusHealthCheckModule.forRootAsync({
configurationFactory: (memoryHealthIndicator: MemoryHealthIndicator) => ({
standardHealthIndicators: [
{
name: 'memory_heap',
check: () => memoryHealthIndicator.checkHeap('memory_heap', 150 * 1024 * 1024),
},
],
}),
inject: [MemoryHealthIndicator],
}),
DefaultNestApplicationListener.forRoot({
staticConfiguration: {
// When running in infrastructure mode, the backend server does not start.
mode: isInfrastructureMode() ? 'silent' : 'listen',
async preListen(options) {
if (options.app) {
options.app.setGlobalPrefix('api');
const swaggerConf = new DocumentBuilder().addBearerAuth().build();
const document = SwaggerModule.createDocument(options.app, swaggerConf);
SwaggerModule.setup('swagger', options.app, document);
if (isInfrastructureMode()) {
writeFileSync(resolve(__dirname, '..', '..', '..', 'app-swagger.json'), JSON.stringify(document));
}
}
},
},
}),
],
core: [
PrismaModule.forRoot({
staticConfiguration: {
schemaFile: join(appFolder, 'src', 'prisma', `${appFeatureName}-${PRISMA_SCHEMA_FILE}`),
featureName: appFeatureName,
prismaModule: isInfrastructureMode() ? { PrismaClient: FakePrismaClient } : import(`@prisma/app-client`),
addMigrationScripts: false,
},
}),
],
feature: [AppModule.forRoot()],
infrastructure: [
InfrastructureMarkdownReportGenerator.forRoot({
staticConfiguration: {
markdownFile: join(appFolder, 'INFRASTRUCTURE.MD'),
skipEmptySettings: true,
},
}),
Pm2.forRoot({
configuration: {
ecosystemConfigFile: join(rootFolder, ECOSYSTEM_CONFIG_FILE),
applicationScriptFile: join('dist/apps/server/main.js'),
},
}),
DockerCompose.forRoot({
configuration: {
dockerComposeFileVersion: '3',
dockerComposeFile: join(appFolder, DOCKER_COMPOSE_FILE),
},
}),
DockerComposePostgreSQL.forRoot(),
DockerComposePostgreSQL.forFeature({
featureModuleName: appFeatureName,
}),
Flyway.forRoot({
staticConfiguration: {
featureName: appFeatureName,
migrationsFolder: join(appFolder, 'src', 'migrations'),
configFile: join(rootFolder, FLYWAY_JS_CONFIG_FILE),
},
}),
],
},
});