Skip to content

Commit

Permalink
Merge pull request #9 from boostcampwm-2024/refactor/response-dto
Browse files Browse the repository at this point in the history
♻️ refactor: Response DTO 적용, request/response 분리
  • Loading branch information
Jo-Minseok authored Jan 9, 2025
2 parents 93d781e + 384461c commit ac64d83
Show file tree
Hide file tree
Showing 42 changed files with 427 additions and 215 deletions.
11 changes: 5 additions & 6 deletions server/src/admin/controller/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import {
} from '@nestjs/common';
import { Request, Response } from 'express';
import { AdminService } from '../service/admin.service';
import { RegisterAdminDto } from '../dto/register-admin.dto';
import { RegisterAdminRequestDto } from '../dto/request/register-admin.dto';
import { ApiTags } from '@nestjs/swagger';
import { ApiResponse } from '../../common/response/common.response';
import { LoginAdminDto } from '../dto/login-admin.dto';
import { LoginAdminRequestDto } from '../dto/request/login-admin.dto';
import { CookieAuthGuard } from '../../common/guard/auth.guard';
import { ApiLoginAdmin } from '../api-docs/loginAdmin.api-docs';
import { ApiReadSessionIdAdmin } from '../api-docs/readSessionIdAdmin.api-docs';
Expand All @@ -33,7 +33,7 @@ export class AdminController {
@HttpCode(HttpStatus.OK)
@UsePipes(ValidationPipe)
async loginAdmin(
@Body() loginAdminDto: LoginAdminDto,
@Body() loginAdminDto: LoginAdminRequestDto,
@Res({ passthrough: true }) response: Response,
@Req() request: Request,
) {
Expand All @@ -49,8 +49,7 @@ export class AdminController {
@Post('/logout')
async logoutAdmin(
@Req() request: Request,
@Res({ passthrough: true })
response: Response,
@Res({ passthrough: true }) response: Response,
) {
await this.adminService.logoutAdmin(request, response);
return ApiResponse.responseWithNoContent(
Expand All @@ -62,7 +61,7 @@ export class AdminController {
@UseGuards(CookieAuthGuard)
@Post('/register')
@UsePipes(ValidationPipe)
async createAdmin(@Body() registerAdminDto: RegisterAdminDto) {
async createAdmin(@Body() registerAdminDto: RegisterAdminRequestDto) {
await this.adminService.createAdmin(registerAdminDto);
return ApiResponse.responseWithNoContent(
'성공적으로 관리자 계정이 생성되었습니다.',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class LoginAdminDto {
export class LoginAdminRequestDto {
@ApiProperty({
example: 'minseokjo',
description: '관리자 로그인 아이디를 입력해주세요.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ApiProperty } from '@nestjs/swagger';

const PASSWORD_REG = /^(?=.*[!@#$%^&*()_+])[A-Za-z0-9!@#$%^&*()_+]+$/;

export class RegisterAdminDto {
export class RegisterAdminRequestDto {
@ApiProperty({
example: 'minseokjo',
description: '관리자 로그인 아이디를 입력해주세요.',
Expand Down
4 changes: 2 additions & 2 deletions server/src/admin/repository/admin.repository.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { Admin } from '../entity/admin.entity';
import { RegisterAdminDto } from '../dto/register-admin.dto';
import { RegisterAdminRequestDto } from '../dto/request/register-admin.dto';

@Injectable()
export class AdminRepository extends Repository<Admin> {
constructor(private dataSource: DataSource) {
super(Admin, dataSource.createEntityManager());
}

async createAdmin(registerAdminDto: RegisterAdminDto) {
async createAdmin(registerAdminDto: RegisterAdminRequestDto) {
const { loginId, password } = registerAdminDto;
const admin = this.create({
loginId,
Expand Down
8 changes: 4 additions & 4 deletions server/src/admin/service/admin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {
UnauthorizedException,
} from '@nestjs/common';
import { Response, Request } from 'express';
import { RegisterAdminDto } from '../dto/register-admin.dto';
import { RegisterAdminRequestDto } from '../dto/request/register-admin.dto';
import { AdminRepository } from '../repository/admin.repository';
import * as bcrypt from 'bcrypt';
import { cookieConfig } from '../../common/cookie/cookie.config';
import * as uuid from 'uuid';
import { RedisService } from '../../common/redis/redis.service';
import { LoginAdminDto } from '../dto/login-admin.dto';
import { LoginAdminRequestDto } from '../dto/request/login-admin.dto';

@Injectable()
export class AdminService {
Expand All @@ -23,7 +23,7 @@ export class AdminService {
) {}

async loginAdmin(
loginAdminDto: LoginAdminDto,
loginAdminDto: LoginAdminRequestDto,
response: Response,
request: Request,
) {
Expand Down Expand Up @@ -90,7 +90,7 @@ export class AdminService {
response.clearCookie('sessionId');
}

async createAdmin(registerAdminDto: RegisterAdminDto) {
async createAdmin(registerAdminDto: RegisterAdminRequestDto) {
let { loginId, password } = registerAdminDto;

const existingAdmin = await this.adminRepository.findOne({
Expand Down
2 changes: 1 addition & 1 deletion server/src/feed/api-docs/searchFeedList.api-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ApiOperation,
ApiQuery,
} from '@nestjs/swagger';
import { SearchType } from '../dto/search-feed.dto';
import { SearchType } from '../dto/request/search-feed.dto';

export function ApiSearchFeedList() {
return applyDecorators(
Expand Down
45 changes: 25 additions & 20 deletions server/src/feed/controller/feed.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
ValidationPipe,
} from '@nestjs/common';
import { FeedService } from '../service/feed.service';
import { QueryFeedDto } from '../dto/query-feed.dto';
import { SearchFeedReq } from '../dto/search-feed.dto';
import { FeedPaginationRequestDto } from '../dto/request/feed-pagination.dto';
import { SearchFeedRequestDto } from '../dto/request/search-feed.dto';
import { Response, Request } from 'express';
import { Observable } from 'rxjs';
import { EventEmitter2 } from '@nestjs/event-emitter';
Expand All @@ -25,7 +25,7 @@ import { ApiReadTrendFeedList } from '../api-docs/readTrendFeedList.api-docs';
import { ApiSearchFeedList } from '../api-docs/searchFeedList.api-docs';
import { ApiUpdateFeedViewCount } from '../api-docs/updateFeedViewCount.api-docs';
import { ApiReadRecentFeedList } from '../api-docs/readRecentFeedList.api-docs';
import { Feed } from '../entity/feed.entity';
import { FeedTrendResponseDto } from '../dto/response/feed-pagination.dto';

@ApiTags('Feed')
@Controller('feed')
Expand All @@ -43,7 +43,7 @@ export class FeedController {
transform: true,
}),
)
async readFeedPagination(@Query() queryFeedDto: QueryFeedDto) {
async readFeedPagination(@Query() queryFeedDto: FeedPaginationRequestDto) {
return ApiResponse.responseWithData(
'피드 조회 완료',
await this.feedService.readFeedPagination(queryFeedDto),
Expand All @@ -54,22 +54,27 @@ export class FeedController {
@Sse('trend/sse')
async readTrendFeedList() {
return new Observable((observer) => {
this.feedService.readTrendFeedList().then((trendData) => {
observer.next({
data: {
message: '현재 트렌드 피드 수신 완료',
data: trendData,
},
this.feedService
.readTrendFeedList()
.then((trendData: FeedTrendResponseDto[]) => {
observer.next({
data: {
message: '현재 트렌드 피드 수신 완료',
data: trendData,
},
});
});
});
this.eventService.on('ranking-update', (trendData: Feed[]) => {
observer.next({
data: {
message: '새로운 트렌드 피드 수신 완료',
data: trendData,
},
});
});
this.eventService.on(
'ranking-update',
(trendData: FeedTrendResponseDto[]) => {
observer.next({
data: {
message: '새로운 트렌드 피드 수신 완료',
data: trendData,
},
});
},
);
});
}

Expand All @@ -82,7 +87,7 @@ export class FeedController {
}),
new ValidationPipe(),
)
async searchFeedList(@Query() searchFeedReq: SearchFeedReq) {
async searchFeedList(@Query() searchFeedReq: SearchFeedRequestDto) {
const data = await this.feedService.searchFeedList(searchFeedReq);
return ApiResponse.responseWithData('검색 결과 조회 완료', data);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IsInt, IsOptional, Min } from 'class-validator';
import { Type } from 'class-transformer';

export class QueryFeedDto {
export class FeedPaginationRequestDto {
@IsOptional()
@Min(0, { message: 'lastId 값은 0 이상이어야 합니다.' })
@IsInt({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Feed } from '../../feed/entity/feed.entity';
import { IsDefined, IsEnum, IsInt, IsString, Min } from 'class-validator';
import { Type } from 'class-transformer';

Expand All @@ -8,7 +7,7 @@ export enum SearchType {
ALL = 'all',
}

export class SearchFeedReq {
export class SearchFeedRequestDto {
@IsDefined({
message: '검색어를 입력해주세요.',
})
Expand Down Expand Up @@ -37,38 +36,7 @@ export class SearchFeedReq {
@Type(() => Number)
limit?: number = 4;

constructor(partial: Partial<SearchFeedReq>) {
constructor(partial: Partial<SearchFeedRequestDto>) {
Object.assign(this, partial);
}
}

export class SearchFeedResult {
constructor(
private id: number,
private blogName: string,
private title: string,
private path: string,
private createdAt: Date,
) {}

static feedsToResults(feeds: Feed[]): SearchFeedResult[] {
return feeds.map((item) => {
return new SearchFeedResult(
item.id,
item.blog.name,
item.title,
item.path,
item.createdAt,
);
});
}
}

export class SearchFeedRes {
constructor(
private totalCount: number,
private result: SearchFeedResult[],
private totalPages: number,
private limit: number,
) {}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FeedView } from '../../feed/entity/feed.entity';
import { FeedView } from '../../entity/feed.entity';

export class FeedPaginationResponseDto {
export class FeedResult {
private constructor(
private id: number,
private author: string,
Expand All @@ -13,8 +13,8 @@ export class FeedPaginationResponseDto {
private isNew: boolean,
) {}

private static toFeedPaginationResponseDto(feed: FeedPaginationResult) {
return new FeedPaginationResponseDto(
private static toResultDto(feed: FeedPaginationResult) {
return new FeedResult(
feed.feedId,
feed.blogName,
feed.blogPlatform,
Expand All @@ -27,10 +27,20 @@ export class FeedPaginationResponseDto {
);
}

public static mapToPaginationResponseDtoArray(
FeedList: FeedPaginationResult[],
) {
return FeedList.map(this.toFeedPaginationResponseDto);
public static toResultDtoArray(feedList: FeedPaginationResult[]) {
return feedList.map(this.toResultDto);
}
}

export class FeedPaginationResponseDto {
private constructor(
private result: FeedResult[],
private lastId: number,
private hasMore: boolean,
) {}

static toResponseDto(result: FeedResult[], lastId: number, hasMore: boolean) {
return new FeedPaginationResponseDto(result, lastId, hasMore);
}
}

Expand All @@ -48,7 +58,7 @@ export class FeedTrendResponseDto {
private viewCount: number,
) {}

private static toFeedTrendResponseDto(feed: FeedView) {
private static toResponseDto(feed: FeedView) {
return new FeedTrendResponseDto(
feed.feedId,
feed.blogName,
Expand All @@ -61,7 +71,7 @@ export class FeedTrendResponseDto {
);
}

public static toFeedTrendResponseDtoArray(FeedList: FeedView[]) {
return FeedList.map(this.toFeedTrendResponseDto);
public static toResponseDtoArray(FeedList: FeedView[]) {
return FeedList.map(this.toResponseDto);
}
}
43 changes: 43 additions & 0 deletions server/src/feed/dto/response/recent.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export class FeedRecentResponseDto {
private constructor(
private id: number,
private author: string,
private blogPlatform: string,
private title: string,
private path: string,
private createdAt: string,
private thumbnail: string,
private viewCount: number,
private isNew: boolean,
) {}

static toResponseDto(feed: FeedRecentRedis) {
return new FeedRecentResponseDto(
feed.id,
feed.blogName,
feed.blogPlatform,
feed.title,
feed.path,
feed.createdAt,
feed.thumbnail,
feed.viewCount,
feed.isNew,
);
}

static toResponseDtoArray(feeds: FeedRecentRedis[]) {
return feeds.map(this.toResponseDto);
}
}

export type FeedRecentRedis = {
id: number;
blogPlatform: string;
createdAt: string;
viewCount: number;
blogName: string;
thumbnail: string;
path: string;
title: string;
isNew?: boolean;
};
Loading

0 comments on commit ac64d83

Please sign in to comment.