Skip to content

Commit 21fa261

Browse files
committed
feat: 컨트롤러에 swagger 적용
1 parent 75a436d commit 21fa261

File tree

10 files changed

+121
-9
lines changed

10 files changed

+121
-9
lines changed

backend/db_name

36 KB
Binary file not shown.

backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"@nestjs/core": "^10.0.0",
2626
"@nestjs/mapped-types": "*",
2727
"@nestjs/platform-express": "^10.0.0",
28+
"@nestjs/swagger": "^8.0.5",
2829
"@nestjs/typeorm": "^10.0.2",
2930
"class-transformer": "^0.5.1",
3031
"class-validator": "^0.14.1",

backend/src/main.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import { NestFactory } from '@nestjs/core';
22
import { AppModule } from './app.module';
33
import { HttpExceptionFilter } from './filter/http-exception.filter';
4+
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
45

56
async function bootstrap() {
67
const app = await NestFactory.create(AppModule);
8+
9+
const config = new DocumentBuilder()
10+
.setTitle('OctoDocs')
11+
.setDescription('OctoDocs API 명세서')
12+
.build();
13+
const documentFactory = () => SwaggerModule.createDocument(app, config);
14+
SwaggerModule.setup('api', app, documentFactory);
715
app.useGlobalFilters(new HttpExceptionFilter());
816
await app.listen(3000);
917
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1+
import { ApiProperty } from '@nestjs/swagger';
12
import { IsString, IsNumber } from 'class-validator';
23

34
export class CreateNodeDto {
5+
@ApiProperty({
6+
example: '노드 제목',
7+
description: '노드 제목',
8+
})
49
@IsString()
510
title: string;
611

12+
@ApiProperty({
13+
example: '14',
14+
description: 'x 좌표입니다.',
15+
})
716
@IsNumber()
817
x: number;
918

19+
@ApiProperty({
20+
example: '14',
21+
description: 'y 좌표입니다.',
22+
})
1023
@IsNumber()
1124
y: number;
1225
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
import { IsString, IsNumber } from 'class-validator';
2+
import { ApiProperty } from '@nestjs/swagger';
23

34
export class UpdateNodeDto {
5+
@ApiProperty({
6+
example: '노드 제목',
7+
description: '노드 제목',
8+
})
49
@IsString()
510
title: string;
611

12+
@ApiProperty({
13+
example: '14',
14+
description: 'x 좌표입니다.',
15+
})
716
@IsNumber()
817
x: number;
918

19+
@ApiProperty({
20+
example: '14',
21+
description: 'y 좌표입니다.',
22+
})
1023
@IsNumber()
1124
y: number;
1225
}

backend/src/node/node.controller.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { NodeService } from './node.service';
1414
import { CreateNodeDto } from './dtos/createNode.dto';
1515
import { UpdateNodeDto } from './dtos/updateNode.dto';
16+
import { ApiOperation } from '@nestjs/swagger';
1617

1718
export enum NodeResponseMessage {
1819
NODE_CREATED = '노드와 페이지를 생성했습니다.',
@@ -25,6 +26,7 @@ export enum NodeResponseMessage {
2526
export class NodeController {
2627
constructor(private readonly nodeService: NodeService) {}
2728

29+
@ApiOperation({ summary: '노드를 생성하면서 페이지도 함께 생성합니다.' })
2830
@Post('/')
2931
@HttpCode(HttpStatus.CREATED)
3032
async createNode(@Body() body: CreateNodeDto): Promise<{ message: string }> {
@@ -34,6 +36,9 @@ export class NodeController {
3436
};
3537
}
3638

39+
@ApiOperation({
40+
summary: '노드를 삭제하면서 페이지도 삭제합니다. (delete: cascade)',
41+
})
3742
@Delete('/:id')
3843
@HttpCode(HttpStatus.OK)
3944
async deleteNode(@Param('id') id: number): Promise<{ message: string }> {
@@ -43,6 +48,7 @@ export class NodeController {
4348
};
4449
}
4550

51+
@ApiOperation({ summary: '노드의 제목, 좌표를 수정합니다.' })
4652
@Patch('/:id')
4753
@HttpCode(HttpStatus.OK)
4854
async updateNode(
@@ -55,6 +61,7 @@ export class NodeController {
5561
};
5662
}
5763

64+
@ApiOperation({ summary: '노드의 좌표를 가져옵니다.' })
5865
@Get(':id/coordinates')
5966
@HttpCode(HttpStatus.OK)
6067
async getCoordinates(@Param('id', ParseIntPipe) id: number) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
1+
import { ApiProperty } from '@nestjs/swagger';
12
import { IsString, IsNumber, IsJSON } from 'class-validator';
23

34
export class CreatePageDto {
5+
@ApiProperty({
6+
example: 'nest.js 사용법',
7+
description: '페이지 제목입니다.',
8+
})
49
@IsString()
510
title: string;
611

12+
@ApiProperty({
13+
example: 'nest를 설치합니다.',
14+
description: '페이지 내용입니다.',
15+
})
716
@IsJSON()
817
content: JSON;
918

19+
@ApiProperty({
20+
example: '14',
21+
description: 'x 좌표입니다.',
22+
})
1023
@IsNumber()
1124
x: number;
1225

26+
@ApiProperty({
27+
example: '14',
28+
description: 'y 좌표입니다.',
29+
})
1330
@IsNumber()
1431
y: number;
1532
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import { IsString, IsJSON } from 'class-validator';
2+
import { ApiProperty } from '@nestjs/swagger';
23

34
export class UpdatePageDto {
5+
@ApiProperty({
6+
example: '페이지 제목입니다.',
7+
description: '페이지 제목.',
8+
})
49
@IsString()
510
title: string;
611

12+
@ApiProperty({
13+
example: "{'doc' : 'type'}",
14+
description: '페이지 내용 JSON 형태',
15+
})
716
@IsJSON()
817
content: JSON;
918
}

backend/src/page/page.controller.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Page } from './page.entity';
1313
import { PageService } from './page.service';
1414
import { CreatePageDto } from './dtos/createPage.dto';
1515
import { UpdatePageDto } from './dtos/updatePage.dto';
16+
import { ApiBody, ApiOperation, ApiResponse } from '@nestjs/swagger';
1617

1718
export enum PageResponseMessage {
1819
PAGE_CREATED = '페이지와 노드를 생성했습니다.',
@@ -26,6 +27,11 @@ export enum PageResponseMessage {
2627
export class PageController {
2728
constructor(private readonly pageService: PageService) {}
2829

30+
@ApiOperation({ summary: '페이지를 생성하고 노드도 생성합니다.' })
31+
@ApiBody({
32+
description: 'post',
33+
type: CreatePageDto,
34+
})
2935
@Post('/')
3036
@HttpCode(HttpStatus.CREATED)
3137
async createPage(@Body() body: CreatePageDto): Promise<{ message: string }> {
@@ -35,6 +41,9 @@ export class PageController {
3541
};
3642
}
3743

44+
@ApiOperation({
45+
summary: '페이지를 삭제하고 노드도 삭제합니다. (cascade delete)',
46+
})
3847
@Delete('/:id')
3948
@HttpCode(HttpStatus.OK)
4049
async deletePage(@Param('id') id: number): Promise<{ message: string }> {
@@ -43,7 +52,7 @@ export class PageController {
4352
message: PageResponseMessage.PAGE_DELETED,
4453
};
4554
}
46-
55+
@ApiOperation({ summary: '페이지 제목, 내용을 수정합니다.' })
4756
@Patch('/:id')
4857
@HttpCode(HttpStatus.OK)
4958
async updatePage(
@@ -56,6 +65,7 @@ export class PageController {
5665
};
5766
}
5867

68+
@ApiOperation({ summary: '모든 페이지를 가져옵니다.' })
5969
@Get()
6070
@HttpCode(HttpStatus.OK)
6171
async findPages(): Promise<{ message: string; pages: Partial<Page>[] }> {
@@ -64,7 +74,7 @@ export class PageController {
6474
pages: await this.pageService.findPages(),
6575
};
6676
}
67-
77+
@ApiOperation({ summary: '특정 페이지를 가져옵니다.' })
6878
@Get('/:id')
6979
@HttpCode(HttpStatus.OK)
7080
async findPage(

backend/yarn.lock

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,11 @@
679679
resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.1.0.tgz#1e3e4bd05c1cc7a0b2ddbd8a03f39f6e4b5e6cfe"
680680
integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==
681681

682+
"@microsoft/tsdoc@^0.15.0":
683+
version "0.15.0"
684+
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d"
685+
integrity sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==
686+
682687
"@nestjs/cli@^10.0.0":
683688
version "10.4.5"
684689
resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-10.4.5.tgz#d6563b87e8ca1d0f256c19a7847dbcc96c76a88e"
@@ -739,6 +744,11 @@
739744
resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz#485d6b44e19779c98d04e52bd1d2bcc7001df0ea"
740745
integrity sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==
741746

747+
748+
version "2.0.6"
749+
resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.0.6.tgz#d2d8523709fd5d872a9b9e0c38162746e2a7f44e"
750+
integrity sha512-84ze+CPfp1OWdpRi1/lOu59hOhTz38eVzJvRKrg9ykRFwDz+XleKfMsG0gUqNZYFa6v53XYzeD+xItt8uDW7NQ==
751+
742752
"@nestjs/platform-express@^10.0.0":
743753
version "10.4.6"
744754
resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-10.4.6.tgz#6c39c522fa66036b4256714fea203fbeb49fc4de"
@@ -761,6 +771,18 @@
761771
jsonc-parser "3.3.1"
762772
pluralize "8.0.0"
763773

774+
"@nestjs/swagger@^8.0.5":
775+
version "8.0.5"
776+
resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-8.0.5.tgz#c8a29ce1cace4f3147ee4dde724543f6e68bec95"
777+
integrity sha512-ZmBdsbQNs3wIN5kCuvAVbz3/ULh3gi814oHTP49uTqAGi1aT0YSatUyncwQOHBOlRT+rwF+TNjoAsZ+twIk/Jw==
778+
dependencies:
779+
"@microsoft/tsdoc" "^0.15.0"
780+
"@nestjs/mapped-types" "2.0.6"
781+
js-yaml "4.1.0"
782+
lodash "4.17.21"
783+
path-to-regexp "3.3.0"
784+
swagger-ui-dist "5.18.2"
785+
764786
"@nestjs/testing@^10.0.0":
765787
version "10.4.6"
766788
resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-10.4.6.tgz#3797a40c0628788e381f299d3c72acac364ca4ef"
@@ -831,6 +853,11 @@
831853
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31"
832854
integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
833855

856+
"@scarf/scarf@=1.4.0":
857+
version "1.4.0"
858+
resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.4.0.tgz#3bbb984085dbd6d982494538b523be1ce6562972"
859+
integrity sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==
860+
834861
"@sinclair/typebox@^0.27.8":
835862
version "0.27.8"
836863
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e"
@@ -3706,6 +3733,13 @@ js-tokens@^4.0.0:
37063733
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
37073734
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
37083735

3736+
[email protected], js-yaml@^4.1.0:
3737+
version "4.1.0"
3738+
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
3739+
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
3740+
dependencies:
3741+
argparse "^2.0.1"
3742+
37093743
js-yaml@^3.13.1:
37103744
version "3.14.1"
37113745
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
@@ -3714,13 +3748,6 @@ js-yaml@^3.13.1:
37143748
argparse "^1.0.7"
37153749
esprima "^4.0.0"
37163750

3717-
js-yaml@^4.1.0:
3718-
version "4.1.0"
3719-
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
3720-
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
3721-
dependencies:
3722-
argparse "^2.0.1"
3723-
37243751
37253752
version "1.1.0"
37263753
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
@@ -5157,6 +5184,13 @@ supports-preserve-symlinks-flag@^1.0.0:
51575184
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
51585185
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
51595186

5187+
5188+
version "5.18.2"
5189+
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.18.2.tgz#62013074374d272c04ed3030704b88db5aa8c0b7"
5190+
integrity sha512-J+y4mCw/zXh1FOj5wGJvnAajq6XgHOyywsa9yITmwxIlJbMqITq3gYRZHaeqLVH/eV/HOPphE6NjF+nbSNC5Zw==
5191+
dependencies:
5192+
"@scarf/scarf" "=1.4.0"
5193+
51605194
51615195
version "4.0.0"
51625196
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205"

0 commit comments

Comments
 (0)