길벗 코딩자율학습단 16일차

donghan378·2025년 2월 1일

16일차

~15.6 댓글 삭제하기 (종이책 p.446~474)

15.4 댓글 생성하기

요청을 받아 응답할 컨트롤러 만들기

  1. CommentApiController로 가서 댓글 생성 요청을 받고 이를 처리하는 create() 메서드를 만든다.
  2. @PostMapping(”/api/articles/{articleId}/comments”)로 댓글 생성을 요청받는다.
  3. 매개변수로는 댓글이 달릴 부모 게시글의 id를 받고, 생성할 댓글 정보를 받아 온다.
  4. 반환형은 댓글 생성 결과를 응답 코드와 함께 보내기 위해 ResponseEntity<CommentDto>로 작성한다.
  5. 댓글 생성을 서비스에 위임하기 위해 CommentService의 create(articleId, dto) 메서드를 호출한다.
  6. 댓글이 성공적으로 생성되었을 때 결과를 클라이언트에 응답하기 위해 return 문을 작성한다.
@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);
}

요청을 처리할 서비스 만들기

컨트롤러에 빨간색으로 표시된 create() 메서드 위에 마우스를 올리고 Create method ‘create’ in ‘CommentService’를 클릭한다.

  1. 먼저 create() 메서드는 DB 내용을 바꾸기 때문에 문제가 생겼을 경우 롤백하기 위해@Transactional을 추가해준다.
  2. articleRepository의 findById(articleId) 메서드를 호출해 부모 게시글을 받아 오고, 만약 부모 게시글이 없다면 orElseThrow() 메서드로 예외를 발생시킨다.
    • orElseThrow() 메서드는 Optional 객체에 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 전달값으로 보낸 예외를 발생시키는 메서드이다.
  3. 예외가 발생하지 않는다면 Comment의 생성 메서드 createComment(dto, article)을 호출해 댓글 엔티티를 만든다.
  4. 만든 댓글 엔티티를 CommentRepository를 통해 DB에 저장한다.
  5. 문제가 없다면 마지막으로 엔티티를 새로운 DTO로 변환해 컨트롤러에 반환한다.
@Transactional
public CommentDto create(Long articleId, CommentDto dto) {
	Article article = articleRepository.findById(articleId).orElseThrow(()new IllegalArgumentException(”댓글 생성 실패!+ “대상 게시글이 없습니다.));
	Comment comment = Comment.createComment(dto, article);
	Comment created = commentRepository.save(comment);
	return CommentDto.createCommentDto(created);
}
  1. 댓글 엔티티를 생성할때 사용했던 createComment() 메서드를 ‘Comment’ 엔티티에 만든다.
  2. 엔티티를 생성할 수 없는 경우에는 예외를 발생시키는데, 2가지로 나누어 작성한다.
    1. dto에 id가 존재하는 경우(댓글을 생성하기 전부터 id값이 있는 경우, DB가 자동으로 생성하기 때문에)
    2. dto에서 가져온 부모 게시글과 엔티티에서 가져온 부모 게시글의 id가 다른 경우
  3. 예외 상황이 발생하지 않았다면 엔티티를 만들어 반환한다.
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());
}

※ JSON 데이터의 키(key) 이름과 이를 받아 저장하는 DTO에 선언된 필드의 변수명이 다를 경우 DTO 필드 위에 @JsonProperty(”키_이름”)을 작성해 줘야 한다. 이렇게 하면 해당 키와 변수가 자동으로 매핑된다.

15.5 댓글 수정하기

요청을 받아 응답할 컨트롤러 만들기

  1. CommentApiController에 댓글 수정을 요청받고 이를 처리할 update() 메서드를 만든다.
  2. @PatchMapping(”/api/comments/{id}”)로 댓글 수정을 요청받는다. 여기서 {id}는 게시글의 id가 아닌 수정 대상인 댓글의 id이다.
  3. 매개변수로 @PatchMapping에서 받아온 id와 JSON 데이터를 받아온 dto를 사용한다.
  4. 댓글 수정 작업을 서비스에 위임하기 위해 CommentService의 update(id, dto) 메서드를 호출한다.
  5. 서비스가 댓글을 성공적으로 수정했다면 반환받은 결과를 return 문을 통해 클라이언트에 응답한다.
@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);
}

요청을 처리할 서비스 만들기

  1. 빨간색으로 처리된 update() 메서드 위에 마우스를 올리고 Create method ‘update’ in ‘CommentService’를 클릭해 메서드를 생성한다.
  2. DB의 내용을 변경하므로 @Transactional을 추가한다.
  3. 수정하려는 댓글이 있는지 commentRepository.findById(id)를 호출해 조회하고 해당 댓글이 없다면 orElseThrow() 메서드로 예외를 발생시킨다.
  4. target.patch(dto) 메서드를 호출해 기존 댓글 엔티티에 수정 정보를 추가한다.
  5. commentRepository.save(target) 메서드를 호출해 DB내용을 갱신한다.
  6. 수정된 댓글 엔티티(updated)를 DTO로 변환해 컨트롤러로 반환한다.
@Transactional
public CommentDto update(Long id, CommentDto dto) {
	Comment target = commentRepository.findById(id).orElseThrow(()new IllegalArgumentException(”댓글 수정 실패!+ “대상 댓글이 없습니다.));
	target.patch(dto);
	Comment updated = commentRepository.save(target);
	return CommentDto.createCommentDto(updated);
}
  1. Comment 엔티티의 patch() 메서드가 작성되지 않았으므로 메서드를 생성한다.
  2. 엔티티를 수정할 수 없는 경우에는 예외를 발생시킨다. 다양한 상황 중에서 댓글 수정 요청 시 URL에 있는 id와 JSON 데이터의 id가 다른 경우를 처리한다.
  3. 예외가 발생하지 않았다면 수정할 내용을 적용해 객체를 갱신한다.
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();
}

15.6 댓글 삭제하기

요청을 받아 응답할 컨트롤러 만들기

  1. CommentApiController에 댓글 삭제를 요청받고 이를 처리할 delete() 메서드를 만든다.
  2. @DeleteMapping(”/api/comments/{id}”)로 댓글 삭제 요청을 받는다.
  3. 매개변수로 @DeleteMapping에서 받아온 id를 작성한다. 반환형은 댓글 삭제 결과를 실어 보내야 하므로 ResponseEntity<CommentDto>로 작성한다.
  4. CommentService의 delete(id) 메서드를 호출해 삭제를 서비스에 위임한다.
  5. 서비스가 댓글을 성공적으로 삭제한다면 반환받은 결과(삭제된 데이터)를 클라이언트에 응답한다.
@DeleteMapping(/api/comments/{id})
public ResponseEntity<CommentDto> delete(@PathVariable Long id) {
	CommentDto deletedDto = commentService.delete(id);
	return ResponseEntity.status(HttpStatus.OK).body(deletedDto);
}

요청을 처리할 서비스 만들기

  1. 빨간색으로 표시된 delete() 메서드 위에 마우스를 올리고 Create method ‘delete’ in ‘CommentService’를 클릭해 메서드를 생성한다.
  2. DB 내용을 변경하므로 @Transactional을 추가한다.
  3. 삭제하려는 댓글이 있는지 commentRepository.findById(id)를 호출하여 조회해 가져오고 없으면 orElseThrow() 메서드로 예외를 발생시킨다.
  4. commentRepository.delete(target) 메서드를 호출해 DB의 해당 댓글을 삭제한다.
  5. 마지막으로 target 엔티티를 DTO로 변환해 반환한다.
@Transactional
public CommentDto delete(Long id) {
	Comment target = commentRepository.findById(id).orElseThrow(()new IllegalArgumentException(”댓글 삭제 실패!+ “대상이 없습니다.));
	commentRepository.delete(target);
	return CommentDto.createCommentDto(target);
}

0개의 댓글