스웨거 문서를 PickType으로 만들 수 있나요?
912
작성한 질문수 15
1. Users.ts(엔티티)
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinTable,
ManyToMany,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { ChannelChats } from './ChannelChats';
import { ChannelMembers } from './ChannelMembers';
import { Channels } from './Channels';
import { DMs } from './DMs';
import { Mentions } from './Mentions';
import { WorkspaceMembers } from './WorkspaceMembers';
import { Workspaces } from './Workspaces';
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
@Index('email', ['email'], { unique: true })
@Entity({ schema: 'sleact', name: 'users' })
export class Users {
@PrimaryGeneratedColumn({ type: 'int', name: 'id' })
id: number;
@ApiProperty({
example: `aaa123@google.com`,
description: '이메일',
required: true,
})
@IsEmail()
@IsNotEmpty()
@Column('varchar', { name: 'email', unique: true, length: 30 })
email: string;
@ApiProperty({
example: `홍길동`,
description: '닉네임',
required: true,
})
@IsString()
@IsNotEmpty()
@Column('varchar', { name: 'nickname', length: 30 })
nickname: string;
@ApiProperty({
example: `123123`,
description: '비밀번호',
required: true,
})
@IsString()
@IsNotEmpty()
@Column('varchar', { name: 'password', length: 100, select: false })
password: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@DeleteDateColumn()
deletedAt: Date | null;
@OneToMany(() => ChannelChats, (channelchats) => channelchats.User)
ChannelChats: ChannelChats[];
@OneToMany(() => ChannelMembers, (channelmembers) => channelmembers.User)
ChannelMembers: ChannelMembers[];
@OneToMany(() => DMs, (dms) => dms.Sender)
DMs: DMs[];
@OneToMany(() => DMs, (dms) => dms.Receiver)
DMs2: DMs[];
@OneToMany(() => Mentions, (mentions) => mentions.Sender)
Mentions: Mentions[];
@OneToMany(() => Mentions, (mentions) => mentions.Receiver)
Mentions2: Mentions[];
@OneToMany(
() => WorkspaceMembers,
(workspacemembers) => workspacemembers.User,
)
WorkspaceMembers: WorkspaceMembers[];
@OneToMany(() => Workspaces, (workspaces) => workspaces.Owner)
OwnedWorkspaces: Workspaces[];
@ManyToMany(() => Workspaces, (workspaces) => workspaces.Members)
@JoinTable({
name: 'workspacemembers',
joinColumn: {
name: 'UserId',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'WorkspaceId',
referencedColumnName: 'id',
},
})
Workspaces: Workspaces[];
@ManyToMany(() => Channels, (channels) => channels.Members)
@JoinTable({
name: 'channelmembers',
joinColumn: {
name: 'UserId',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'ChannelId',
referencedColumnName: 'id',
},
})
Channels: Channels[];
}
2. join.request.dto
import { PickType } from '@nestjs/mapped-types';
import { Users } from '../../entities/Users';
export class JoinRequestDto extends PickType(Users, [
'email',
'nickname',
'password',
] as const) {}
3. user.dto
import { JoinRequestDto } from './join.request.dto';
import { ApiProperty } from '@nestjs/swagger';
export class UserDto extends JoinRequestDto {
@ApiProperty({
example: `1`,
description: '아이디',
required: true,
})
id: number;
}
4. users.controller
import {
Body,
Controller,
ForbiddenException,
Get,
NotFoundException,
Post,
Req,
Res,
UseGuards,
UseInterceptors,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { JoinRequestDto } from './dto/join.request.dto';
import { User } from '../common/decorators/user.decorator';
import { UndefinedToNullInterceptor } from '../common/interceptors/undefinedToNull.interceptor';
import { LocalAuthGuard } from '../auth/local-auth.guard';
import { NotLoggedInGuard } from '../auth/not-logged-in.guard';
import { LoggedInGuard } from '../auth/logged-in.guard';
import {
ApiCookieAuth,
ApiOperation,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { Users } from '../entities/Users';
import { UserDto } from './dto/user.dto';
@ApiTags('USERS')
@UseInterceptors(UndefinedToNullInterceptor)
@Controller('api/users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@ApiCookieAuth('connect.sid')
@ApiOperation({ summary: '내 정보 가져오기' })
@ApiResponse({
type: UserDto,
})
@Get()
async getMyProfile(@User() user: Users) {
return user || false;
}
@ApiResponse({
status: 500,
description: 'Server Error..',
})
@ApiResponse({
status: 200,
description: '성공!',
})
@ApiOperation({ summary: '회원가입' })
@UseGuards(NotLoggedInGuard)
@Post()
async join(@Body() body: JoinRequestDto) {
const user = this.usersService.findByEmail(body.email);
if (!user) {
throw new NotFoundException();
}
const result = await this.usersService.join(
body.email,
body.nickname,
body.password,
);
if (result) {
return 'ok';
} else {
throw new ForbiddenException();
}
}
@ApiResponse({
status: 200,
description: '성공',
type: UserDto,
})
@ApiOperation({ summary: '로그인' })
@UseGuards(LocalAuthGuard)
@Post('login')
async login(@User() user: Users) {
return user;
}
@ApiCookieAuth('connect.sid')
@ApiOperation({ summary: '로그아웃' })
@UseGuards(LoggedInGuard)
@Post('logout')
async logout(@Req() req, @Res() res) {
req.logOut();
res.clearCookie('connect.sid', { httpOnly: true });
res.send('ok');
}
}
----------------------------
스웨거 문서
1. Dto 관련 스키마

2. usersDto를 사용한 결과

3. joinRequestDto를 사용한 결과

마지막 결과 쪽에 제가 생각한 것은 빈칸이 아니라
{
email : "aaa123@google.com"
nickname: "홍길동"
passwork: "123123"
}
이었는데 빈칸으로 나오네요.. 혹시 잘못한 부분이 있을까요?
답변 2
0
코드 상에 잘못은 없는 것 같은데요. extends가 문제인지 PickType이 문제인지 테스트 한 번 해봐야할 것 같습니다.
1
PickType import 가 잘 못되어 있는 문제였습니다.
import { PickType } from '@nestjs/swagger'
import { PickType } from '@nestjs/mapped-types'
이 두개가 있는데 mapped-types로 import 되어 있으면 swagger 문서에 출력되지 않습니다.
@nestjs/swagger 로 변경해주세요~~!
강의자료는 어디서 다운받나요?
0
114
4
질문 있습니다.
0
298
3
코드 편집기 확장 프로그램
0
209
2
(질문)비밀 저장소에 접근하기 위한 인증 정보는 로컬 .env에 저장하는지?
0
144
2
(질문)외부 저장소를 통한 환경변수 불러오기 비동기 질문
0
168
3
로그인을 해도 LoggedInGuard쪽에서 false값이 나옵니다.
0
152
2
로그인방법이 고민됩니다.
0
190
2
yarn seed 명령어 실행 시 데이터 삽입 안됨
0
297
4
yarn run db:create 시에 발생하는 데코레이터 오류
0
242
2
npm run db:create 시에 발생하는 decorating 오류
0
232
2
RxJS 디버깅 질문 있습니다.
0
189
3
CacheManager에 대해 질문 있습니다.
0
174
2
로깅은 어떻게 하는게 효율적일까요?
0
224
1
CORS 질문 있습니다.
0
418
2
쿠키 옵션에 대해서 질문 있습니다.
0
184
2
로그아웃 요청이 403 forbidden 에러가 나는데 왜그런걸까요??
0
449
1
401 unauthorized문제
0
288
1
가드의 장점에 대해서 질문이 있습니다.
0
225
1
로그 관리에 대해 질문 있습니다.
0
252
2
CORS 에러 질문 있습니다.
0
319
2
배포 환경 DB 연결 질문 있습니다.
0
411
2
socket io 미 연결 문제 (nest & flutter)
1
1154
3
no elements in sequence 에러 관해서 질문이 있습니다.
0
454
1
start:dev-backup으로 돌리면 핫 리로딩이 되요 정상인가요?
0
322
1





