모든 작업의 흐름은
1. 컨트롤러 만들기
2. 서비스 만들기
로 이루어진다. 또한 생성, 수정, 삭제는 DB에 접근하기 때문에 @Transactional 어노테이션을 주어야 한다.
댓글 생성
1. 컨트롤러 만들기
// CommentApiController.java
// 2. 댓글 생성
@PostMapping("/api/articles/{articleId}/comments")
public ResponseEntity<CommentDto> create(@PathVariable Long articleId,
@RequestBody CommentDto dto) {
// 서비스에 위임
CommentDto createdDto = commentService.create(articleId, dto);
// 결과 응답
return ResponseEntity.status(HttpStatus.OK).body(createdDto);
}
@PathVariable : 요청 url에서 {aritcleId} 를 가져옴
댓글 생성 작업은 서비스에게 위임하고 결과를 서비스에게 받아옴
2. 서비스 만들기
// CommentService.java
@Transactional
public CommentDto create(Long articleId, CommentDto dto) {
// 1. 게시글 조회 및 예외 발생
Article article = articleRepository.findById(articleId)
.orElseThrow(() -> new IllegalArgumentException("댓글 생성 실패!" +
" 대상 게시글이 없습니다."));
// 2. 댓글 엔티티 생성
Comment comment = Comment.createComment(dto, article);
// 3. 댓글 엔티티를 DB에 저장
Comment created = commentRepository.save(comment);
// 4. DTO로 변환해 반환
return CommentDto.createCommentDto(created);
}
댓글 생성은 DB에 접근하여 데이터를 바꾸기 때문에 중간에 에러가 발생하면 롤백하여 DB를 원상태로 복구해야함.
@Transactional 어노테이션 추가. 댓글 생성 작업을 서비스에서 한 뒤 생성된 데이터를 DTO로 변환하여 반환한다.
orElseThrow()는 option 객체(null이 될 수도 있는 객체)에 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 전달값으로 보낸 예외를 발생시킨다. 위 코드에서 전달값은 IllegalArguentException 클래스로, 메서드가 잘못됐거나 부적합한 전달값을 보냈음을 나타낸다.
여기서 댓글 엔티티를 생성하게 되는데, 엔티티를 생성할 수 없는 경우는 예외를 발생시키고, 아니면 엔티티를 생성하고 반환하면 된다.
// Comment.java
public static Comment createComment(CommentDto dto, Article article) {
// 예외 발생
if (dto.getId() != null)
throw new IllegalArgumentException("댓글 생성 실패! 댓글의 id가 없어야 합니다.");
if (dto.getArticleId() != article.getId())
throw new IllegalArgumentException("댓글 생성 실패! 게시글의 id가 잘못됐습니다.");
// 엔티티 생성 및 반환
return new Comment(
dto.getId(), // 댓글 아이디
article, // 부모 게시글
dto.getNickname(), // 댓글 닉네임
dto.getBody() // 댓글 본문
);
}
댓글 수정
1. 컨트롤러 만들기
// CommentApiController.java
// 3. 댓글 수정
@PatchMapping("/api/comments/{id}")
public ResponseEntity<CommentDto> update(@PathVariable Long id,
@RequestBody CommentDto dto) {
// 서비스에 위임
CommentDto updatedDto = commentService.update(id, dto);
// 결과 응답
return ResponseEntity.status(HttpStatus.OK).body(updatedDto);
}
댓글 생성과 같이 서비스에 위임하고, 그 결과값을 dto로 받아와 응답코드와 함께 보낸다.
2. 서비스 만들기
//CommentService.java
@Transactional
public CommentDto update(Long id, CommentDto dto) {
// 1. 댓글 조회 및 예외 발생
Comment target = commentRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("댓글 수정 실패!" +
" 대상 댓글이 없습니다."));
// 2. 댓글 수정
target.patch(dto);
// 3. DB 갱신
Comment updated = commentRepository.save(target);
// 4. 댓글 엔티티를 DTO로 변환 및 반환
return CommentDto.createCommentDto(updated);
}
DB에 접근하기때문에 @Transactional 어노테이션 주입. 댓글을 엔티티에서 수정하기 위해 patch()를 만든다.
// Comment.java
public void patch(CommentDto dto) {
// 예외 발생
if (this.id != dto.getId())
throw new IllegalArgumentException("댓글 수정 실패! 잘못된 id가 입력됐습니다.");
// 객체 갱신
if (dto.getNickname() != null)
this.nickname = dto.getNickname();
if (dto.getBody() != null)
this.body = dto.getBody();
}
url 요청으로 받은 id와 불러온 id가 다를 경우 예외를 발생시켜 중단시킨다.
만일 id가 일치한다면, nickname과 body를 바꿀 수 있도록 데이터가 있을경우 내용을 갱신한다.
댓글 삭제
1. 컨트롤러 만들기
// CommnetApiController.java
// 4. 댓글 삭제
@DeleteMapping("/api/comments/{id}")
public ResponseEntity<CommentDto> delete(@PathVariable Long id) {
// 서비스에 위임
CommentDto deleteDto = commentService.delete(id);
// 결과 응답
return ResponseEntity.status(HttpStatus.OK).body(deleteDto);
}
위의 요청들과 같이 서비스에 위임하고 서비스에서 결과를 받아 응답코드와 함께 보낸다.
2. 서비스 만들기
//CommentService.java
@Transactional
public CommentDto delete(Long id) {
// 1. 댓글 조회 및 예외 발생
Comment target = commentRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("댓글 삭제 실패!" +
" 대상이 없습니다."));
// 2. 댓글 삭제
commentRepository.delete(target);
// 3. 삭제 댓글을 DTO로 변환 및 반환
return CommentDto.createCommentDto(target);
}
만일 삭제할 댓글의 id를 조회했을때 해당 댓글에 대한 id가 없을 경우(데이터가 없을 경우) 예외를 발생시킨다.
해당 id가 존재한다면 댓글을 삭제한 후, 삭제한 댓글을 dto로 변환하여 반환한다.
api 요청을 보내서 200 코드가 뜬다면 구현 성공!
'코딩 자율학습단 > 학습 일지' 카테고리의 다른 글
[DAY 18] 댓글 등록 View 페이지 구현 및 REST API 요청 (0) | 2024.08.25 |
---|---|
[DAY 17] 댓글 목록 View 페이지 구현 및 모델 등록하기 (0) | 2024.08.21 |
[DAY 15] 댓글 REST API - 서비스, 컨트롤러, Read 구현 (0) | 2024.08.19 |
[DAY 14] 댓글 CRUD : InvalidDataAccessApiUsageException 에러 (0) | 2024.08.18 |
[DAY 13] JUnit5 테스트 코드 작성 (0) | 2024.08.18 |