저번에 등록(create) 기능까지 만들었고, 이번엔 조회(Read), 수정(Update), 삭제(Delete) 기능을 만들어보려 한다. 우선 조회부터 시작쓰.
게시글의 상세내용을 보기 위해서 클라쪽에서 서버 쪽으로 게시글id를 넘기도록 할 건데, 이 때 url변수로 넘기든가(ex : /board/1) 아님 쿼리스트링 형태로 넘기든가(ex : /board?id=1) 해야 한다. (body에 적는 방법 등도 있지만..패쓰) 아무래도 대중적인 방법은 url변수로 하는 방법이라 어떻게 하는지 알아봤다.
방법은 간단했다. @PathVariable이라는 어노테이션을 사용하면 됐다! 방법은
- GetMapping(Post든 뭐든 상관 X)의 url입력하는 부분에 {받을 변수명}
- 메서드의 파라미터로 @PathVariable("받을 변수명")
이다. 다음과 같이 활용해줬다.
@GetMapping("/{id}")
public BoardResponseDTO getBoard(@PathVariable("id") Long id) {
Board board = boardService.findBoard(id).get();
// ... 생략
}
그리고 다음과 같이 BoardResponseDTO를 만들어줬다.
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class BoardResponseDTO {
private Long boardId;
private String writerNickname;
private String title;
private String content;
private Long hits;
private Long like;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
private int categoryId;
public static BoardResponseDTO from(Member writer, Board board) {
return new BoardResponseDTO(
board.getBoardId(),
writer.getNickname(),
board.getTitle(),
board.getContent(),
board.getHits(),
board.getLike(),
board.getCreatedDate(),
board.getUpdatedDate(),
board.getCategoryId()
);
}
}
요즘 이 토이플젝을 하면서 참고하는 분이 있는데, 그 분은 이런 식으로 from메서드를 만들어 활용하는 식으로 하는 것 같아 참고해봤다. AccessLevel지정해주는 건 Lombok으로 만들어주는 생성자의 접근지정자를 설정하는거다. private로 한 것은 외부에서 요 놈의 인스턴스를 만드는 것을 막아주므로, BoardResponseDTO를 만들려면 from메서드를 사용하는 수밖에 없다!
암튼! 그래서 결과는..
성공~! 저번에 인터셉터 통해서 응답값들을 통일시켜준 방식 그대로 뱉어지는 모습도 곁들여 볼 수 있었다.
그 다음으론 삭제기능을 만들어보기로 했다. 삭제 기능에서의 고민은 바로 "삭제 권한". 글의 작성자만이 본인의 글을 삭제할 수 있도록 해야 할 것이다. 저번 학기에 프론트를 했을 때는 따로 프론트 쪽에서 현재 로그인한 유저의 정보를 가지고 있었기 때문에, 내가 지금 보고 있는 글의 작성자와 내가 가진 유저의 정보가 같으면 그 글에 삭제버튼을 보이게 하는 식으로 이를 만들었다. 그러나 지금 드는 생각은 어차피 contextHolder?거기에 현재 로그인한 유저의 정보를 가진다 하니 걔를 통해서 비교해줄 수 있을 것 같다!
그래서 다음과 같이 일단 delete에 해당하는 메서드를 만들어줬다.
@DeleteMapping("/{id}")
public String deleteBoard(@AuthenticationPrincipal Member member, @PathVariable("id") Long id) {
Board board = boardService.findBoard(id).get();
Member writer = board.getWriter();
if (writer.getEmail().equals(member.getEmail())) {
return "same";
}
return "diff";
}
현재 유저와 게시글의 작성자 이메일이 같다면 same을 뱉고, 다르면 diff를 뱉을 거다. 우선 작성자로 로그인하고 request를 보내봤다! 결과는..
같다고 잘 나왔다. 이번엔 다른 사용자로 로그인하고 (즉 포스트맨 상에서는 헤더에 담는 토큰을 다른 걸로 설정) 보내봤다. 결과는..
다르다고 잘 나온다! 삭제코드 자체는 BoardRepository에 deleteById메서드를 만들어 다음과 같이 구현해줬다.
@Override
public void deleteById(Long id) {
Board board = em.find(Board.class, id);
em.remove(board);
}
암튼 그렇게 해서 만든 삭제기능은..
27번 게시물이 잘 삭제된 것을 볼 수 있었다.
마지막으로 수정 기능을 만들 차례. 제목이나 본문의 내용이 잘 바뀌는지도 중요하겠지만, 아무래도 관건은
- 수정일이 알아서 업데이트되는지, 생성일자는 변함없는지
- 게시물의 id가 그대로 유지되는지
정도가 될 것 같다.
컨트롤러에서 다음과 같이 코드를 작성했다.
@PutMapping("/{id}")
public BoardResponseDTO updateBoard(
@AuthenticationPrincipal Member member,
@PathVariable Long id,
@RequestBody BoardDTO boardDTO) {
Board oldBoard = boardService.findBoard(id).get();
Member writer = oldBoard.getWriter();
if (writer.getEmail().equals(member.getEmail())) {
Board updatedBoard = boardService.updateBoard(id, boardDTO);
return BoardResponseDTO.from(writer, updatedBoard);
}
return null;
}
역시나 요청을 보낸 사람의 정보와 게시글 작성자가 같을 때에만 수정이 이뤄지게 했다. 그리고 게시글 작성 때 사용했던 BoardDTO를 수정할 때도 그대로 재탕해줬다. 어차피 게시글 작성할 때 작성하는 부분이 수정할 때 작성하는 부분이랑 같으니까..
BoardRepository에서 다음과 같이 코드를 짜 수정이 이루어지게끔 했다.
@Override
public Board updateBoard(Long id, BoardDTO boardDTO) {
Board board = em.find(Board.class, id);
board.setTitle(boardDTO.getTitle());
board.setContent(boardDTO.getContent());
board.setCategoryId(boardDTO.getCategoryId());
em.persist(board);
return board;
}
세터 메서드들을 사용해 Board엔티티의 내용물들을 바꿔치기해주고 저장해주는 식. entitymanager의 save라는 메서드가 인자로 받는 entity의 id값이 있냐없냐에 따라 insert를 할지 update를 할지 결정해준다고 한다. 이 경우에선 이미 board는 id가 있는 상태이니 update가 될 것이다.
이제 한 번 시험해볼 차례! 우선 수정 전 db상황은 다음과 같았다. 여기서 28번 게시물을 바꿀 거다.
포스트맨을 사용해 수정 테스트하기. 결과는..!
우선 응답값 자체는 문제가 없어보인다! 과연 db에서는..?
수정한 부분들이 잘 바뀌었음을 확인했다. title, content, category_id 컬럼값이 바뀌었으며 board_id나 writer는 변함없는 걸 볼 수 있다. 또한 created_date는 변화가 없고 updated_date에만 변화가 생겼음을 잘 확인할 수 있었다.
'PROJECT > 개발일지' 카테고리의 다른 글
애플로그인 만들기 - id token(itentity token) 검증하기(java) (0) | 2023.08.24 |
---|---|
Oauth2 & JWT를 활용한 로그인&회원가입을 개발하며 마주하고 고민한 것들 (0) | 2023.08.12 |
[백엔드 야생 개발일지] 게시글 등록 기능 만들어보기 (2) (0) | 2023.02.27 |
[백엔드 야생 개발일지] 게시글 등록 기능 만들어보기 (1) (0) | 2023.02.20 |
[백엔드 야생 도전일기] 인터셉터를 통해 응답값 통일해보기 (2) - 인터셉터 뜯어보기 (0) | 2023.02.05 |