Skip to content

Commit

Permalink
refactor: Must be return HTTP Status OK(200)
Browse files Browse the repository at this point in the history
  • Loading branch information
son-daehyeon committed Aug 16, 2024
1 parent 389b8db commit 54378b2
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 55 deletions.
14 changes: 9 additions & 5 deletions src/common/http/filter/exception.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
HttpStatus,
NotFoundException,
} from '@nestjs/common';
import { ApiException } from '@wink/swagger';

@Catch(HttpException)
@Catch(ApiException)
export class DefaultExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
catch(exception: ApiException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();

response.status(exception.getStatus()).json({ error: true, content: exception.message });
response.json({ code: exception.getStatus(), error: true, content: exception.message });
}
}

Expand All @@ -23,6 +23,10 @@ export class NotFoundExceptionFilter implements ExceptionFilter {
const ctx = host.switchToHttp();
const response = ctx.getResponse();

response.status(HttpStatus.NOT_FOUND).json({ error: true, content: 'API Endpoint not found.' });
response.json({
code: HttpStatus.NOT_FOUND,
error: true,
content: '엔드포인트를 찾을 수 없습니다.',
});
}
}
13 changes: 11 additions & 2 deletions src/common/http/interceptor/api-response.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,30 @@ import {
NestInterceptor,
} from '@nestjs/common';

import { ApiException } from '@wink/swagger';

import { Response } from 'express';
import { catchError, map, Observable, throwError } from 'rxjs';

@Injectable()
export class ApiResponseInterceptor implements NestInterceptor {
private readonly logger: Logger = new Logger(ApiResponseInterceptor.name);

intercept(_context: ExecutionContext, next: CallHandler): Observable<unknown> {
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
const ctx = context.switchToHttp();
const response: Response = ctx.getResponse();

response.status(HttpStatus.OK);

return next.handle().pipe(
map((content) => ({
code: HttpStatus.OK,
error: false,
content: content ?? {},
})),

catchError((err) => {
if (!(err instanceof HttpException)) {
if (!(err instanceof ApiException)) {
this.logger.error(err);
return throwError(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const ApiCustomErrorResponse = (errors: Type<ApiException>[]) => {
`error${index}`,
{
value: {
code: error.getStatus(),
error: true,
content: error.getResponse(),
},
Expand Down
15 changes: 5 additions & 10 deletions src/common/util/swagger/decorator/api-custom-response.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@ import { ApiExtraModels, ApiResponse, getSchemaPath } from '@nestjs/swagger';

import { ApiCustomResponseDto } from '../dto';

interface ApiCustomResponseOptions {
type?: Type<unknown>;
status: HttpStatus;
}

class EmptyResponse {}

export const ApiCustomResponse = (options: ApiCustomResponseOptions) => {
options.type ??= EmptyResponse;
export const ApiCustomResponse = (type?: Type<unknown>) => {
type ??= EmptyResponse;

return applyDecorators(
ApiExtraModels(options.type, ApiCustomResponseDto),
ApiExtraModels(type, ApiCustomResponseDto),
ApiResponse({
status: options.status,
status: HttpStatus.OK,
description: '성공',
content: {
'application/json': {
Expand All @@ -27,7 +22,7 @@ export const ApiCustomResponse = (options: ApiCustomResponseOptions) => {
},
{
properties: {
content: { $ref: getSchemaPath(options.type) },
content: { $ref: getSchemaPath(type) },
},
},
],
Expand Down
4 changes: 4 additions & 0 deletions src/common/util/swagger/dto/api-custom.response.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { HttpStatus } from '@nestjs/common';
import { ApiProperty } from '@nestjs/swagger';

export class ApiCustomResponseDto {
@ApiProperty({ type: Number, description: 'HTTP 응답 코드', default: HttpStatus.OK })
code!: number;

@ApiProperty({ type: Boolean, description: '오류 여부', default: false })
error!: boolean;

Expand Down
20 changes: 7 additions & 13 deletions src/domain/auth/controller/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
import { Body, Controller, Get, Post } from '@nestjs/common';
import { ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';

import {
Expand Down Expand Up @@ -35,10 +35,9 @@ export class AuthController {
constructor(private readonly authService: AuthService) {}

@Post('/login')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '로그인' })
@ApiProperty({ type: LoginRequestDto })
@ApiCustomResponse({ type: LoginResponseDto, status: HttpStatus.OK })
@ApiCustomResponse(LoginResponseDto)
@ApiCustomErrorResponse([
MemberNotFoundException,
WrongPasswordException,
Expand All @@ -49,20 +48,18 @@ export class AuthController {
}

@Post('/refresh')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '토큰 재발행' })
@ApiProperty({ type: RefreshRequestDto })
@ApiCustomResponse({ type: RefreshResponseDto, status: HttpStatus.OK })
@ApiCustomResponse(RefreshResponseDto)
@ApiCustomErrorResponse([InvalidRefreshTokenException, MemberNotFoundException])
async refresh(@Body() request: RefreshRequestDto): Promise<RefreshResponseDto> {
return this.authService.refresh(request);
}

@Post('/register')
@HttpCode(HttpStatus.CREATED)
@ApiOperation({ summary: '회원가입' })
@ApiProperty({ type: RegisterRequestDto })
@ApiCustomResponse({ status: HttpStatus.CREATED })
@ApiCustomResponse()
@ApiCustomErrorResponse([
InvalidVerifyTokenException,
AlreadyRegisteredByEmailException,
Expand All @@ -73,30 +70,27 @@ export class AuthController {
}

@Post('/register/code')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '인증코드 전송' })
@ApiProperty({ type: SendCodeRequestDto })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([AlreadyRegisteredByEmailException])
async sendCode(@Body() request: SendCodeRequestDto): Promise<void> {
return this.authService.sendCode(request);
}

@Post('/register/code/verify')
@HttpCode(HttpStatus.CREATED)
@ApiOperation({ summary: '인증 토큰 발급' })
@ApiProperty({ type: VerifyCodeRequestDto })
@ApiCustomResponse({ type: VerifyCodeResponseDto, status: HttpStatus.CREATED })
@ApiCustomResponse(VerifyCodeResponseDto)
@ApiCustomErrorResponse([InvalidVerifyCodeException])
async verifyCode(@Body() request: VerifyCodeRequestDto): Promise<VerifyCodeResponseDto> {
return this.authService.verifyCode(request);
}

@Get('/me')
@HttpCode(HttpStatus.OK)
@AuthAccount()
@ApiOperation({ summary: '인증 토큰으로 정보 조회' })
@ApiCustomResponse({ type: MyInfoResponseDto, status: HttpStatus.OK })
@ApiCustomResponse(MyInfoResponseDto)
@ApiCustomErrorResponse([...AuthAccountException])
getMyInfo(@ReqMember() member: Member): MyInfoResponseDto {
return this.authService.myInfo(member);
Expand Down
20 changes: 7 additions & 13 deletions src/domain/member/controller/member.admin.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Body, Controller, Get, HttpCode, HttpStatus, Patch, Post } from '@nestjs/common';
import { Body, Controller, Get, Patch, Post } from '@nestjs/common';
import { ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';

import { AuthAdminAccount, AuthAdminAccountException, ReqMember } from '@wink/auth/guard';
Expand All @@ -25,21 +25,19 @@ export class MemberAdminController {
constructor(private readonly memberAdminService: MemberAdminService) {}

@Get('/waiting')
@HttpCode(HttpStatus.OK)
@AuthAdminAccount()
@ApiOperation({ summary: '회원가입 승인 대기 목록' })
@ApiCustomResponse({ type: GetWaitingMembersResponseDto, status: HttpStatus.OK })
@ApiCustomResponse(GetWaitingMembersResponseDto)
@ApiCustomErrorResponse([...AuthAdminAccountException])
async getWaitingMembers(): Promise<GetWaitingMembersResponseDto> {
return this.memberAdminService.getWaitingMembers();
}

@Post('/waiting/approve')
@HttpCode(HttpStatus.OK)
@AuthAdminAccount()
@ApiOperation({ summary: '회원가입 승인' })
@ApiProperty({ type: ApproveWaitingMemberRequestDto })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([...AuthAdminAccountException, NotWaitingMemberException])
async approveWaitingMember(
@ReqMember() member: Member,
Expand All @@ -49,11 +47,10 @@ export class MemberAdminController {
}

@Post('/waiting/reject')
@HttpCode(HttpStatus.OK)
@AuthAdminAccount()
@ApiOperation({ summary: '회원가입 거부' })
@ApiProperty({ type: RejectWaitingMemberRequestDto })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([...AuthAdminAccountException, NotWaitingMemberException])
async rejectWaitingMember(
@ReqMember() member: Member,
Expand All @@ -63,21 +60,19 @@ export class MemberAdminController {
}

@Get()
@HttpCode(HttpStatus.OK)
@AuthAdminAccount()
@ApiOperation({ summary: '부원 목록' })
@ApiCustomResponse({ type: GetMembersForAdminResponseDto, status: HttpStatus.OK })
@ApiCustomResponse(GetMembersForAdminResponseDto)
@ApiCustomErrorResponse([...AuthAdminAccountException])
async getMembers(): Promise<GetMembersForAdminResponseDto> {
return this.memberAdminService.getMembers();
}

@Patch('/role')
@HttpCode(HttpStatus.OK)
@AuthAdminAccount()
@ApiOperation({ summary: '부원 권한 수정' })
@ApiProperty({ type: UpdateMemberRoleRequestDto })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([
...AuthAdminAccountException,
NotApprovedMemberException,
Expand All @@ -91,11 +86,10 @@ export class MemberAdminController {
}

@Patch('/fee')
@HttpCode(HttpStatus.OK)
@AuthAdminAccount()
@ApiOperation({ summary: '부원 회비 납부 여부 수정' })
@ApiProperty({ type: UpdateMemberFeeRequestDto })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([
...AuthAdminAccountException,
NotApprovedMemberException,
Expand Down
17 changes: 5 additions & 12 deletions src/domain/member/controller/member.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Patch,
Put,
UploadedFile,
Expand Down Expand Up @@ -35,19 +33,17 @@ export class MemberController {
constructor(private readonly memberService: MemberService) {}

@Get()
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '부원 목록' })
@ApiCustomResponse({ type: GetMembersResponseDto, status: HttpStatus.OK })
@ApiCustomResponse(GetMembersResponseDto)
async getMembers(): Promise<GetMembersResponseDto> {
return this.memberService.getMembers();
}

@Put('/me/info')
@HttpCode(HttpStatus.OK)
@AuthAccount()
@ApiOperation({ summary: '내 정보 수정' })
@ApiProperty({ type: UpdateMyInfoRequestDto })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([...AuthAccountException])
async updateMyInfo(
@ReqMember() member: Member,
Expand All @@ -57,11 +53,10 @@ export class MemberController {
}

@Patch('/me/password')
@HttpCode(HttpStatus.OK)
@AuthAccount()
@ApiOperation({ summary: '내 비밀번호 수정' })
@ApiProperty({ type: UpdateMyPasswordRequestDto })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([...AuthAccountException, WrongPasswordException])
async updateMyPassword(
@ReqMember() member: Member,
Expand All @@ -71,13 +66,12 @@ export class MemberController {
}

@Patch('/me/avatar')
@HttpCode(HttpStatus.OK)
@AuthAccount()
@UseInterceptors(FileInterceptor('avatar', { fileFilter: AvatarFilter }))
@ApiOperation({ summary: '내 프로필 사진 수정' })
@ApiConsumes('multipart/form-data')
@ApiProperty({ type: UpdateMyAvatarRequestDto })
@ApiCustomResponse({ type: UpdateMyAvatarResponseDto, status: HttpStatus.OK })
@ApiCustomResponse(UpdateMyAvatarResponseDto)
@ApiCustomErrorResponse([...AuthAccountException, ...AvatarFilterException])
async updateMyAvatar(
@ReqMember() member: Member,
Expand All @@ -87,10 +81,9 @@ export class MemberController {
}

@Delete('/me/avatar')
@HttpCode(HttpStatus.OK)
@AuthAccount()
@ApiOperation({ summary: '내 프로필 사진 삭제' })
@ApiCustomResponse({ status: HttpStatus.OK })
@ApiCustomResponse()
@ApiCustomErrorResponse([...AuthAccountException])
async deleteMyAvatar(@ReqMember() member: Member): Promise<void> {
await this.memberService.deleteMyAvatar(member);
Expand Down

0 comments on commit 54378b2

Please sign in to comment.