add swagger

This commit is contained in:
Sergey Krylov 2025-06-12 14:13:07 +03:00
parent b6f4107c8a
commit 8024b36280
6 changed files with 134 additions and 8 deletions

View File

@ -25,6 +25,7 @@
"@nestjs/core": "^11.0.1",
"@nestjs/mapped-types": "*",
"@nestjs/platform-express": "^11.0.1",
"@nestjs/swagger": "^11.2.0",
"@prisma/client": "^6.9.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",

View File

@ -1,4 +1,5 @@
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { AllExceptionsFilter } from './common/filters/all-exceptions.filter';
@ -6,7 +7,20 @@ import { ResponseInterceptor } from './common/interceptors/response.interceptor'
import { loggerMiddlewareFunc } from './common/middlewares/logger/logger.middleware';
async function bootstrap() {
const config = new DocumentBuilder()
.setTitle('Nest.js Course')
.setDescription('Documentation for nest.js')
.setVersion('0.0.1')
.setContact('Krylov Sergey', 'https://ksv741.tech', 'ksv741@mail.ru')
.setLicense('MIT', 'https://github.com')
.build();
const app = await NestFactory.create(AppModule);
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('/docs', app, document, {
jsonDocumentUrl: 'docs/swagger.json',
yamlDocumentUrl: 'docs/swagger.yaml',
customSiteTitle: 'Nest.js base course',
});
app.useGlobalPipes(new ValidationPipe());
app.use(loggerMiddlewareFunc);
app.useGlobalInterceptors(new ResponseInterceptor());

View File

@ -1,3 +1,4 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsArray,
IsInt,
@ -11,20 +12,39 @@ import {
import { Actor } from 'generated/prisma';
export class MovieDto {
@ApiProperty({
description: 'Название фильма',
example: 'Fight Club',
type: String,
})
@IsNotEmpty()
@IsString()
title: string;
@ApiProperty({
description: 'Год выпуска',
example: 1995,
type: Number,
})
@IsNotEmpty()
@IsInt()
@Min(1888)
@Max(new Date().getFullYear())
releaseYear: number;
@ApiProperty({
description: 'Список актеров',
example: ['1234', '5678'],
type: [String],
})
@IsArray()
@IsUUID('4', { each: true })
actorIds: Actor['id'][];
@ApiProperty({
description: 'URL постера',
example: 'https://storage.example.com/posters/12345.jpg',
})
@IsUrl()
imageUrl: string;
}

View File

@ -0,0 +1,24 @@
import { ApiProperty } from '@nestjs/swagger';
export class MovieResponse {
@ApiProperty({
description: 'Id фильма',
example: '123456',
type: String,
})
id: string;
@ApiProperty({
description: 'Название фильма',
example: 'Fight Club',
type: String,
})
title: string;
@ApiProperty({
description: 'Год выпуска',
example: 1995,
type: Number,
})
releaseYear: number;
}

View File

@ -3,28 +3,66 @@ import {
Controller,
Delete,
Get,
HttpStatus,
Param,
Post,
Put,
} from '@nestjs/common';
import {
ApiNotFoundResponse,
ApiOkResponse,
ApiOperation,
ApiParam,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { MovieDto } from './dto/movie.dto';
import { MovieResponse } from './dto/response.dto';
import { MovieService } from './movie.service';
import { Movie } from 'generated/prisma';
@ApiTags('Movies')
@Controller('movies')
export class MovieController {
constructor(private readonly movieService: MovieService) {}
@ApiOperation({
summary: 'Список фильмов',
description: 'Получить список всех фильмов',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Фильмы найдены',
})
@Get()
public findAll() {
return this.movieService.findAll();
}
@ApiOperation({
summary: 'Поллучить фильм',
description: 'Получить фильм по id',
})
@ApiParam({ name: 'id', type: 'string', description: 'ID фильма' })
@ApiOkResponse({ description: 'Фильм найден', type: MovieResponse })
@ApiNotFoundResponse({
description: 'Филь не найден',
example: {
status: 404,
message: 'Not found movie with id 22',
timestamp: '2025-06-12T10:46:30.694Z',
path: '',
},
})
@Get(':id')
public findById(@Param('id') id: Movie['id']) {
return this.movieService.findById(id);
}
@ApiOperation({
summary: 'Добавить фильм',
description: 'Добавить фильм в коллекцию',
})
@Post()
public create(@Body() dto: MovieDto) {
return this.movieService.create(dto);

View File

@ -858,6 +858,11 @@
resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.1.0.tgz#1e3e4bd05c1cc7a0b2ddbd8a03f39f6e4b5e6cfe"
integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==
"@microsoft/tsdoc@0.15.1":
version "0.15.1"
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz#d4f6937353bc4568292654efb0a0e0532adbcba2"
integrity sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==
"@napi-rs/nice-android-arm-eabi@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz#9a0cba12706ff56500df127d6f4caf28ddb94936"
@ -1017,7 +1022,7 @@
path-to-regexp "8.2.0"
tslib "2.8.1"
"@nestjs/mapped-types@*":
"@nestjs/mapped-types@*", "@nestjs/mapped-types@2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz#b9b536b7c3571567aa1d0223db8baa1a51505a19"
integrity sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==
@ -1044,6 +1049,18 @@
jsonc-parser "3.3.1"
pluralize "8.0.0"
"@nestjs/swagger@^11.2.0":
version "11.2.0"
resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-11.2.0.tgz#a1b10620a9f90c78edf897a9386dc4f3e014387e"
integrity sha512-5wolt8GmpNcrQv34tIPUtPoV1EeFbCetm40Ij3+M0FNNnf2RJ3FyWfuQvI8SBlcJyfaounYVTKzKHreFXsUyOg==
dependencies:
"@microsoft/tsdoc" "0.15.1"
"@nestjs/mapped-types" "2.1.0"
js-yaml "4.1.0"
lodash "4.17.21"
path-to-regexp "8.2.0"
swagger-ui-dist "5.21.0"
"@nestjs/testing@^11.0.1":
version "11.1.2"
resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-11.1.2.tgz#af5f03f1b58318db7d5a0b1dbf7006bc8145d288"
@ -1144,6 +1161,11 @@
dependencies:
"@prisma/debug" "6.9.0"
"@scarf/scarf@=1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.4.0.tgz#3bbb984085dbd6d982494538b523be1ce6562972"
integrity sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==
"@sec-ant/readable-stream@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c"
@ -4055,6 +4077,13 @@ js-tokens@^4.0.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@4.1.0, js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
js-yaml@^3.13.1:
version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
@ -4063,13 +4092,6 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsesc@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
@ -5331,6 +5353,13 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
swagger-ui-dist@5.21.0:
version "5.21.0"
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.21.0.tgz#aed230fe6e294c9470217e67697d601e3bb8eb9d"
integrity sha512-E0K3AB6HvQd8yQNSMR7eE5bk+323AUxjtCz/4ZNKiahOlPhPJxqn3UPIGs00cyY/dhrTDJ61L7C/a8u6zhGrZg==
dependencies:
"@scarf/scarf" "=1.4.0"
symbol-observable@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205"