오늘 공부한 것
* 실전 프로젝트 대댓글기능 구현
오늘은 대댓글 기능을 구현하기로했다
처음 해보는 기능이어서 구글링을 해보니 나오는건QueryDSL을 이용하여 구한하는것만 나오더라... 그래서 이 기술을 써볼까 아는것 중에 해볼까 고민을 많이하다가
일단은 Comments에다가 Replies를 List 형태로 넣어보기로 하고 코드를 구현했다
아직 테스트를 하지못했는데 팀원분께서 작성하신 Post 가 완료되었으니내일은 간단히 테스트를 해봐야겠다
1. Controller
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class RepliesController {
private final RepliesService repliesService;
// 대댓글 생성
@PostMapping("/post/{postId}/comments/{commentId}/replies")
public ResponseEntity<RepliesResponseDto> repliesCreate(@PathVariable("postId") Long postId,
@PathVariable("commentId") Long commentId,
@RequestBody RepliesRequestDto requestDto,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
return ResponseEntity.ok(repliesService.repliesCreate(postId, commentId, requestDto, userDetails.getUsers()));
}
// 대댓글 조회
@GetMapping("/post/{postId}/comments/{commentId}/replies")
public ResponseEntity<List<RepliesResponseDto>> repliesList(@PathVariable("postId") Long postId,
@PathVariable("commentId") Long commentId) {
return ResponseEntity.ok(repliesService.repliesList(postId, commentId));
}
// 대댓글 수정
@PutMapping("/post/{postId}/comments/{commentId}/replies/{repliesId}")
public ResponseEntity<RepliesResponseDto> repliesUpdate(@PathVariable("postId") Long postId,
@PathVariable("commentId") Long commentId,
@PathVariable("repliesId") Long repliesId,
@RequestBody RepliesRequestDto request,
@RequestBody PostsRequestDto requestDto,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
return ResponseEntity.ok(repliesService.repliesUpdate(postId, commentId, repliesId, request, requestDto, userDetails.getUsers()));
}
// 대댓글 삭제
@DeleteMapping("/post/{postId}/comments/{commentId}/replies/{repliesId}")
public ResponseEntity<MessageResponseDto> repliesDelete(@PathVariable("postId") Long postId,
@PathVariable("commentId") Long commentId,
@PathVariable("repliesId") Long repliesId,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
return ResponseEntity.ok(repliesService.repliesDelete(postId, commentId, repliesId, userDetails.getUsers()));
}
}
2. Entity
@Entity
@Getter
@NoArgsConstructor
@Table(name = "replies")
public class Replies extends Timestamped {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="replies_id")
private Long id;
@Column(nullable = false, unique = true)
private String nickname;
@Column(nullable = false, length = 500)
private String contents;
@ManyToOne
@JoinColumn(name = "comments_id")
private Comments comments;
public Replies(RepliesRequestDto requestDto) {
this.nickname = requestDto.getNickname();
this.contents = requestDto.getContents();
}
public void update(RepliesRequestDto requestDto) {
this.nickname = requestDto.getNickname();
this.contents = requestDto.getContents();
}
public void setComments(Comments comments) {
this.comments = comments;
}
}
3. Dto
@Getter
public class RepliesRequestDto {
private String nickname;
private String contents;
}
@Getter
public class RepliesResponseDto {
private Long id;
private String contents;
private String nickname;
private LocalDateTime createAt;
private LocalDateTime modifiedAt;
public RepliesResponseDto(Replies replies) {
this.id = replies.getId();
this.contents = replies.getContents();
this.nickname = replies.getNickname();
this.createAt = replies.getCreatedAt();
this.modifiedAt = replies.getModifiedAt();
}
}
4. Repository
public interface RepliesRepository extends JpaRepository<Replies, Long> {
List<Replies> findByCommentIdAndPostIdOrderByCreatedAtDesc(Long commentId, Long postId);
}
5. Service
@Service
@RequiredArgsConstructor
public class RepliesService {
private final RepliesRepository repliesRepository;
private final CommentsRepository commentsRepository;
private final PostsRepository postsRepository;
// 대댓글 생성
public RepliesResponseDto repliesCreate(Long postId,
Long commentId,
RepliesRequestDto requestDto,
Users users) {
Posts posts = postsRepository.findById(postId).orElseThrow(
() -> new CustomException(ErrorCode.POST_NOT_EXIST)); // 존재하지 않는 게시글입니다
Comments comments = commentsRepository.findById(commentId).orElseThrow(
() -> new CustomException(ErrorCode.POST_NOT_EXIST)); // 존재하지 않는 게시글입니다
Replies replies = new Replies(requestDto);
comments.addReplies(replies);
posts.addComments(comments);
MessageResponseDto messageResponseDto = new MessageResponseDto(
"대댓글을 작성하였습니다", 200
);
return new RepliesResponseDto(repliesRepository.save(replies));
}
// 대댓글 조회
public List<RepliesResponseDto> repliesList(Long postId,
Long commentId) {
return repliesRepository.findByCommentIdAndPostIdOrderByCreatedAtDesc(commentId,postId).stream().map(RepliesResponseDto::new).toList();
}
@Transactional
// 대댓글 수정
public RepliesResponseDto repliesUpdate(Long postId,
Long commentId,
Long repliesId,
RepliesRequestDto request,
PostsRequestDto requestDto,
Users users) {
Posts posts = postsRepository.findById(postId).orElseThrow(
() -> new CustomException(ErrorCode.POST_NOT_EXIST)); // 존재하지 않는 게시글입니다
Comments comments = commentsRepository.findById(commentId).orElseThrow(
() -> new CustomException(ErrorCode.POST_NOT_EXIST)); // 존재하지 않는 게시글입니다
Replies replies = findById(repliesId);
if (users.getUserRole() == UserRoleEnum.ADMIN) {
replies.update(request);
posts.update(requestDto);
MessageResponseDto messageResponseDto = new MessageResponseDto(
"대댓글을 수정하였습니다", 200
);
return new RepliesResponseDto(replies);
} else {
if (users.getNickName().equals(comments.getNickname())) {
replies.update(request);
MessageResponseDto messageResponseDto = new MessageResponseDto(
"대댓글을 수정하였습니다", 200
);
return new RepliesResponseDto(replies);
} else {
throw new CustomException(ErrorCode.NOT_ALLOWED); // 권한이 없습니다
}
}
}
// 대댓글 삭제
public MessageResponseDto repliesDelete(Long postId,
Long commentId,
Long repliesId,
Users users) {
Posts posts = postsRepository.findById(postId).orElseThrow(
() -> new CustomException(ErrorCode.POST_NOT_EXIST)); // 존재하지 않는 게시글입니다
Comments comments = commentsRepository.findById(commentId).orElseThrow(
() -> new CustomException(ErrorCode.POST_NOT_EXIST)); // 존재하지 않는 게시글입니다
Replies replies = findById(repliesId);
if (users.getUserRole() == UserRoleEnum.ADMIN) {
repliesRepository.delete(replies);
return new MessageResponseDto("대댓글을 삭제하였습니다", 200);
} else {
if (users.getNickName().equals(comments.getNickname())) {
repliesRepository.delete(replies);
MessageResponseDto messageResponseDto = new MessageResponseDto(
"대댓글을 삭제하였습니다", 200
);
return new MessageResponseDto("대댓글을 삭제하였습니다", 200);
} else {
throw new CustomException(ErrorCode.NOT_ALLOWED); // 권한이 없습니다
}
}
}
private Replies findById(Long id) {
return repliesRepository.findById(id).orElseThrow(
() -> new NullPointerException("유효하지 않은 댓글입니다")
);
}
}
'항해99' 카테고리의 다른 글
23.10.09 항해 99 16기 실전 프로젝트 5일차 (0) | 2023.10.09 |
---|---|
23.09.26~10.08 항해 99 16기 8주차 회고록 (1) | 2023.10.09 |
23.10.06 항해 99 16기 실전 프로젝트 3일차 (0) | 2023.10.06 |
23.10.05 항해 99 16기 실전 프로젝트 2일차 (1) | 2023.10.05 |
23.10.04 항해 99 16기 실전 프로젝트 1일차 (1) | 2023.10.04 |