[게시판 프로젝트] ArticleRequest와 ArticleResponse를 사용하는 상황의 차이 이해하기, DTO를 따로 만들어 사용하는 이유
2024. 8. 26. 19:07ㆍCS/프로젝트
요청 응답 DTO를 사용하는 상황의 차이를 이해하고,
왜 요청/응답을 DTO로 만들어서 사용하는지
그 이점과 예시를 알아보자
1. ArticleRequest: 클라이언트에서 서버로 데이터를 전송할 때 사용
- 사용 목적
- ArticleRequest는 주로 클라이언트(사용자)로부터 입력된 데이터를 서버로 전달받을 때 사용됩니다.
- 예를 들어, 사용자가 게시글 작성 폼에 내용을 입력하고 제출할 때, 그 데이터는 ArticleRequest 객체로 매핑됩니다.
- 즉, 사용자 입력 데이터를 서버가 받을 수 있도록 하기 위한 객체입니다.
- 사용 예시
- 게시글 작성: 사용자가 작성한 게시글의 제목, 내용 등을 서버로 전송할 때 ArticleRequest가 사용됩니다.
- 게시글 수정: 기존 게시글을 수정하는 폼에서도 수정된 데이터를 받아올 때 사용됩니다.
@PostMapping("/form")
public String postNewArticle(ArticleRequest articleRequest, @AuthenticationPrincipal BoardPrincipal boardPrincipal) {
articleService.saveArticle(articleRequest.toDto(boardPrincipal.toDto()));
return "redirect:/articles";
}
- 이 메소드에서 ArticleRequest는 사용자가 작성한 게시글 데이터를 받아오는 데 사용됩니다.
2. ArticleResponse: 서버에서 클라이언트로 데이터를 전송할 때 사용
- 사용 목적
- ArticleResponse는 서버에서 클라이언트로 데이터를 전송할 때 사용됩니다. 주로 서버가 클라이언트에게 특정 데이터를 제공할 때 이 객체를 사용하여 응답(response)을 만듭니다.
- 데이터베이스에서 조회한 Article 객체나 비즈니스 로직을 통해 생성된 데이터를 클라이언트가 이해할 수 있는 형식으로 변환합니다.
- 사용 예시
- 게시글 조회: 서버가 특정 게시글의 내용을 클라이언트에게 반환할 때, 그 데이터를 ArticleResponse객체로 만들어 전달합니다.
- 게시글 목록: 여러 게시글을 조회하여 목록으로 반환할 때, 각 게시글을 ArticleResponse 객체로 변환하여 전송합니다.
@GetMapping("/{articleId}")
public String article(@PathVariable Long articleId, ModelMap map) {
ArticleWithCommentsResponse article = ArticleWithCommentsResponse.from(articleService.getArticleWithComments(articleId));
map.addAttribute("article", article);
map.addAttribute("articleComments", article.articleCommentsResponse());
map.addAttribute("totalCount", articleService.getArticleCount());
map.addAttribute("searchTypeHashtag", SearchType.HASHTAG);
return "articles/detail";
}
- 이 메소드에서 ArticleResponse (또는 ArticleWithCommentsResponse)는 데이터베이스에서 가져온 게시글 데이터를 클라이언트에게 전달하기 위해 사용됩니다.
응답/요청 DTO를 따로 만들어 사용하는 이유
응답(Response)과 요청(Request) DTO(Data Transfer Object)를 따로 만들어 사용하는 이유는 애플리케이션의 계층 구조를 명확하게 하고, 각 계층 간의 데이터 전송을 효과적으로 관리하기 위해서입니다. 이러한 접근 방식은 여러 가지 이점을 제공합니다.
1. 책임 분리 (Separation of Concerns)
- 요청(Request) DTO는 클라이언트가 서버로 전송하는 데이터를 캡슐화합니다. 이 DTO는 주로 사용자의 입력 데이터(예: 폼 데이터)를 받아서 서버로 전달하는 역할을 합니다.
- 응답(Response) DTO는 서버가 클라이언트로 전송하는 데이터를 캡슐화합니다. 이 DTO는 주로 서버에서 처리된 결과나 데이터베이스에서 조회된 데이터를 클라이언트에게 반환하는 데 사용됩니다.
- 이처럼 요청과 응답을 분리하면 각 DTO가 명확한 역할을 가지게 되어 코드의 가독성과 유지보수성이 향상됩니다.
2. 보안 (Security)
- 클라이언트가 서버로 전송하는 데이터와 서버가 클라이언트로 보내는 데이터는 서로 다를 수 있습니다. 예를 들어, 클라이언트가 보내야 할 정보는 게시글의 제목과 내용이지만, 서버가 반환하는 데이터에는 게시글의 작성일이나 작성자 정보 등이 추가될 수 있습니다.
- 요청과 응답 DTO를 분리하면 클라이언트가 불필요하게 민감한 데이터를 전달하지 않도록 하거나, 서버에서 민감한 데이터를 클라이언트로 반환하지 않도록 할 수 있습니다.
3. 유연성 및 확장성 (Flexibility and Scalability)
- 요청과 응답 DTO를 분리하면, 서버의 내부 구조나 데이터베이스 스키마에 변화가 있어도 클라이언트와의 인터페이스를 안정적으로 유지할 수 있습니다.
- 예를 들어, 서버 쪽에서 데이터베이스 스키마가 변경되어도, 요청이나 응답 DTO를 적절히 조정하면 클라이언트와의 인터페이스를 그대로 유지할 수 있습니다.
4. 데이터 검증 (Validation)
- 요청 DTO는 클라이언트로부터 전달된 데이터를 서버에서 검증하는 데 사용될 수 있습니다. 이 과정에서 필요한 데이터 유효성 검사를 요청 DTO에서 수행할 수 있습니다.
- 응답 DTO는 서버에서 클라이언트로 데이터를 전달하기 전에 필요한 가공을 수행할 수 있습니다.
5. 명확한 API 설계
- 요청과 응답 DTO를 분리하여 사용하면 API 설계가 명확해집니다. API 사용자(클라이언트)에게 어떤 데이터가 필요한지, 그리고 어떤 데이터를 반환할지를 명확하게 정의할 수 있습니다.
요청(Request) DTO
public record ArticleRequest(
String title,
String content,
String hashtag
) {
public static ArticleRequest of(String title, String content, String hashtag) {
return new ArticleRequest(title, content, hashtag);
}
public ArticleDto toDto(UserAccountDto userAccountDto) {
return ArticleDto.of(
userAccountDto,
title,
content,
hashtag
);
}
}
- 클라이언트 → 서버: 클라이언트가 서버로 보내는 게시글의 제목, 내용, 해시태그 정보를 캡슐화합니다.
- toDto 메소드: ArticleRequest를 ArticleDto로 변환하여 서비스 계층으로 전달합니다.
응답(Response) DTO
public record ArticleResponse(
Long id,
String title,
String content,
String hashtag,
String author,
LocalDateTime createdAt
) {
public static ArticleResponse from(Article article) {
return new ArticleResponse(
article.getId(),
article.getTitle(),
article.getContent(),
article.getHashtag(),
article.getAuthor(),
article.getCreatedAt()
);
}
}
- 서버 → 클라이언트: 서버가 클라이언트로 반환하는 게시글 ID, 제목, 내용, 해시태그, 작성자, 작성일 등의 정보를 캡슐화합니다.
- from 메소드: 데이터베이스에서 가져온 Article 엔티티를 ArticleResponse로 변환하여 클라이언트에게 반환합니다.
'CS > 프로젝트' 카테고리의 다른 글
[게시판 프로젝트] 게시판 검색 구현 (0) | 2024.08.26 |
---|---|
[게시판 프로젝트] 페이지네이션(Pagination) 구현 (0) | 2024.08.26 |
[게시판 프로젝트] ArticleController 코드 뜯어 보기를 통해서, 서비스계층과 레포지토리 DTO간 호출/응답 관계 이해하기 (0) | 2024.08.26 |
[게시판 프로젝트] 뷰 구현(3) - Boostrap 프레임워크 라이브러리 사용해서 CSS 적용하기 (0) | 2024.08.17 |
[게시판 프로젝트] 뷰 구현(2) - Spring Security를 사용하여 로그인 페이지 구현 (0) | 2024.08.17 |