유용한 자료 올려주셔서 감사합니다.
자료를 보면서 JPA 관련한 토이프로젝트를 해보고 있는데 몇가지 궁금증이 생겨 글을 남깁니다.
어느 아티클이 있고 해당 아티클에 댓글이 달리는 작은 서비스를 만들어보고 있습니다.
Article 과 Comment 라는 엔티티이고 둘의 관계는 일대다 관계로 설정되어 있습니다.
Article 의 기준에서 Comment 는 여러개가 달릴 수 있고, ( 1 : N )
Comment 의 기준에서 여러 개의 Comment 들은 하나의 Article 에 달릴 수 있다고 판단하여 ( N : 1 )
관계로 두었습니다.
첫번째 질문.
하나의 아티클에 댓글 작성 시 dto 작성에 관한 질문.
만약에 사용자가 특정 아티클에 대해서 댓글을 작성한다고 가정한다면, 저는 해당 Dto 를 Commenet 에 관한 Dto 로 작성하고 아래와 같이 표현하였습니다.
CommentOneRequestDto.class
@Getter
public class CommentOneRequestDto {
private Long articleId;
@NotBlank(message = "comment is not empty.")
private String comment;
public Comment toEntity() {
return Comment.builder()
.comment(this.comment)
.build();
}
}
하나의 댓글을 등록함에 있어서 해당 Dto 가 article 에 대한 Id 를 Dto 내부에 가지고 있는게 올바른 방법인지 헷갈려서 질문을 남깁니다. (해당 Dto 는 Comment 쪽의 Controller 에서 받는것으로 정의되어 있습니다. )
Comment 에 관한 컨트롤러는 아래와 같이 구성되어 있습니다.
CommentController.class
@PostMapping("/comment")
public ResponseEntity<CommentOneResponseDto> saveComment(@Valid @RequestBody CommentOneRequestDto dto,
BindingResult bindingResult) throws ValidationException {
- 댓글이 특정한 아티클에 작성되려면 분명히 아티클에 대한 id 값을 알고 있어야 하는데, 이 아이디 값을 어떻게 서버로 전달하는게 좋을지에 대해 생각하다가 저는 위와 같이 생각하였습니다. id 값을 @PathVariable 로 받을까라는 생각을 하였지만, 댓글을 작성하는데 댓글 api 단에서 아티클 id를 받는게 좋지 않다고 판단해서 위와 같이 작성을 하였습니다.
두번째 질문.
댓글을 작성하였을 때 서비스 레이어에서 댓글을 등록하는 방법에 관한 질문
하나의 댓글을 작성하고 저장하는 로직이 댓글 서비스 레이어에서 있다고 한다면 레이어에 2 개의 레파지토리가 필요하더군요. ArticleRepository, CommentRepository 저는 이렇게 하는 것이 좋은지 혹은 CommentService 에서 ArticleService 에 대한 메소드를 호출하는 것이 나은지 궁금합니다.
CommentService.class :: 두 개의 레파지토리를 가지고 있는 경우
@Service
public class CommentService {
@Autowired
private ArticleRepository articleRepository;
@Autowired
private CommentRepository commentRepository;
public CommentOneResponseDto addNewComment(CommentOneRequestDto dto) throws ArticleNotFoundException{
Article article = articleRepository.findById(dto.getArticleId())
.orElseThrow(() -> new ArticleNotFoundException("아티클이 존재하지 않습니다."));
Comment comment = dto.toEntity();
comment.setArticle(article);
article.addComment(comment);
commentRepository.save(comment);
return new CommentOneResponseDto(comment);
}
}
CommentService.class :: 하나의 레파지토리를 가지고, ArticleService 의 메소드를 이용하는 경우
@Service
public class CommentService {
@Autowired
private ArticleInternalService articleInternalService;
@Autowired
private CommentRepository commentRepository;
public CommentOneResponseDto addNewComment(CommentOneRequestDto dto){
Article article = articleInternalService.findById(dto.getArticleId());
Comment comment = dto.toEntity();
comment.setArticle(article);
article.addComment(comment);
commentRepository.save(comment);
return new CommentOneResponseDto(comment);
}
}
- 저는 댓글이 작성되는 서비스 레이어가 직접적으로 ArticleRepository 를 건드리는게 맞다고 판단하지 않아서 ArticleService 이외의 ArticleInternalService 를 두어서 서비스 레이어간의 데이터 송수신? 에 관한 목적으로 다른 서비스 레이어를 호출하는 형태로 두었습니다. 이 부분에 대해서 제대로된 기준을 판단하기 어려웠고 이렇게 질문을 남깁니다.
질문이 두 개지만 질문을 하기위한 설명을 제대로 하는게 좋을 것 같아서 좀 장황하게 작성이 되었습니다. 다시한번 좋은 자료 공유해주셔서 감사드리고 혹 시간되실 때, 답변주시면 감사하겠습니다.