스프링 부트3 제 15장
드디어 댓글 REST API를 만드는군요!
스프링 부트3 제 15장
댓글 컨트롤러와 서비스
CommentController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// ... 생략
@RestController
public class CommentApiController {
@Autowired
private CommentService commentService;
// 1. 댓글 조회
@GetMapping("/api/articles/{articleId}/comments")
public ResponseEntity<List<CommentDto>> comments(@PathVariable Long articleId) {
// 서비스에 위임
List<CommentDto> dtos = commentService.comments(articleId);
// 결과 응답
return ResponseEntity.status(HttpStatus.OK).body(dtos);
}
// 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);
}
// 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);
}
// 4. 댓글 삭제
@DeleteMapping("/api/comments/{id}")
public ResponseEntity<CommentDto> delete(@PathVariable Long id) {
// 서비스에 위임
CommentDto deletedDto = commentService.delete(id);
// 결과 응답
return ResponseEntity.status(HttpStatus.OK).body(deletedDto);
}
}
CommentService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// ... 생략
@Service
public class CommentService {
@Autowired
private CommentRepository commentRepository;
@Autowired
private ArticleRepository articleRepository;
public List<CommentDto> comments(Long articleId) {
// 1. 댓글 조회
List<Comment> comments = commentRepository.findByArticleId(articleId);
// 2. 엔티티 -> DTO 반환
/*List<CommentDto> dtos = new ArrayList<CommentDto>();
for (int i = 0; i < comments.size(); i++) {
Comment c = comments.get(i); // 조회한 댓글 엔티티 하나씩 가져오기
CommentDto dto = CommentDto.createCommentDto(c); // 엔티티를 DTO로 변환
dtos.add(dto); // 변환한 DTO를 dtos에 저장
}*/
// 3. 결과 반환
return commentRepository.findByArticleId(articleId) // 댓글 엔티티 목록 조회
.stream() // 댓글 엔티티 목록을 스트림으로 변환
.map(comment -> CommentDto.createCommentDto(comment)) // 엔티티를 DTO로 매핑
.collect(Collectors.toList()); // 스트림을 리스트로 변환
}
@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);
}
@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);
}
public CommentDto delete(Long id) {
// 1. 댓글 조회 및 예외 발생
Comment target = commentRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("댓글 삭제 실패!" +
"대상이 없습니다."));
// 2. 댓글 삭제
commentRepository.delete(target);
// 3. 삭제 댓글을 DTO로 변환 및 반환
return CommentDto.createCommentDto(target);
}
}
for문을 간결하게 적기 위해 stream을 사용했다. 자세한 설명은 여기를 참조.
CommentDto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ... 생략
@AllArgsConstructor
@NoArgsConstructor
@Getter
@ToString
public class CommentDto {
private Long id;
//@JsonProperty("article_id") 만약 json 데이터의 키 이름과 dto 필드명이 다른 경우 이걸로 서로 매핑해야함, 만약 키 이름이 "article_id"인 경우 주석 해제
private Long articleId;
private String nickname;
private String body;
public static CommentDto createCommentDto(Comment comment) { // 객체 없이 만들 수 있는 생성 메서드
return new CommentDto(
comment.getId(),
comment.getArticle().getId(),
comment.getNickname(),
comment.getBody()
);
}
}
엔티티를 DTO로 변환해주는 메서드가 들어있다. 솔직히 DTO가 없었으면 좋겠다…
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.