ResponseDto 활용하여 특정 값만 조회하기
스파르타코딩 측에서 제공된 Spring Boot 입문 강의를 따라가며 구현한 GET API는
기존에 POST했던 API의 모든 값을 가져오는 API였다.
즉 기존에 게시하였던 모든 게시글의 모든 값들을 가져오게 구현되어있었다. 심지어 password까지도.
기존코드
Entity Class
package com.sparta.week03.domain;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@NoArgsConstructor
@Getter
@Entity
public class Post extends Timestamped {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
private Long id;
@Column(nullable = false)
private String username;
@Column(nullable = false)
private String contents;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private long password;
public Post(String username, String contents, String title, long password) {
this.username = username;
this.contents = contents;
this.title = title;
this.password = password;
}
public Post(PostRequestDto requestDto) {
this.username = requestDto.getUsername();
this.contents = requestDto.getContents();
this.title = requestDto.getTitle();
this.password = requestDto.getPassword();
}
public void update(PostRequestDto requestDto){
this.username = requestDto.getUsername();
this.contents = requestDto.getContents();
this.title = requestDto.getTitle();
this.password = requestDto.getPassword();
}
}
Controller
@GetMapping("/api/posts")
public List<Post> readAllPost(){
return postRepository.findAllByOrderByModifiedAtDesc();
}
Repository
package com.sparta.week03.domain;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface PostRepository extends JpaRepository<Post, Long> {
List<Post> findAllByOrderByModifiedAtDesc();
}
하지만 과제에서 요구하는 내용은 제목, 작성자명, 작성날짜의 값만 작성 날짜 기준 내림차순으로 출력하는 것이었다.
아직 내 수준에 위 기능을 한 번에 구현하는 것은 무리가 있다고 판단되어 우선은 작성한 id n 게시글의 일부 값만
출력시키는 것 부터 구현해보기로 하였다.
우선 Controller에 집중하였다.
기존의 Controller에서 게시글을 가져오는 메서드인 readAllPost의 경우 return하는 값이 List<Post>로 설정되어 있었기에
Domain Class의 모든 배열들을 가져올 것이 아니기에, 이 부분부터 수정해줘야된다고 판단하였고
이를 위한 방법으로 responseDto를 생성하고자 하였다.
responseDto
package com.sparta.week03.domain;
public class PostResponseDto{
private String title;
private String username;
}
수정 날짜 기준 내림차순으로 정렬하는 부분은 이미 강의를 따라 작성하였던 repository 내에서도 구현되었었기에
Repository 단에서도 이 responseDto를 통하여 걸러진 값들을 바탕으로 다시 한 번 정렬해줄 수 있도록 코드를 수정하였다.
Repository (1차수정)
package com.sparta.week03.domain;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface PostRepository extends JpaRepository<Post, Long> {
PostResponseDto findAllByOrderByModifiedAtDesc();
}
Controller에서도 return 값을 기존의 Domain Class의 배열이 아닌 방금 전 작성한 responseDto를 통해 걸러진 값으로 변경하였다.
Controller(1차수정)
@GetMapping("/api/posts")
public PostResponseDto readAllPost() {
return postRepository.findAllByOrderByModifiedAtDesc();
}
POST 결과
GET 결과
생각과는 달리 바로 문제가 발생하였다.
GET으로 값을 받아오지 못하는 것이었다.
처음에는 방법 자체가 잘못된거라 생각하여 방법도 바꿔보기도하고 그러다 다시 지금의 방법으로 돌아오기도하고
몇 시간동안 헤매였다.
그렇게 구글링을 수십차례 반복하던 와중, responseDto 단에서 공통적으로 발견되는 어노테이션이 있었고
이를 반영하여 responseDto를 수정 해보았다.
responseDto(1차수정)
package com.sparta.week03.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
@AllArgsConstructor
@Data
public class PostResponseDto extends Timestamped{
private String title;
private String username;
}
@AllArgsConstructor 그리고 @Data 어노테이션을 추가한 것이다.
GET 결과2
너무나 다행히도 특정값만을 출력하는데 성공하였다! 몇 시간 동안 헤맨 후 나온 성과였기에 눈물나게 기뻤다.
그렇담 이를 가능토록 만들어준 위 두 개의 어노테이션은 무엇일까?
잊기 전에 반드시 기록해둬야한다고 생각하였다.
@AllArgsConstructor - 클래스에 존재하는 모든 필드에 대한 생성자를 자동으로 생성해준다 @Data - @Getter,@Setter,@RequiredArgsConstructor,@ToString,@EqualsAndHashCode을 한꺼번에 설정 |
아직 각 생성자들의 차이를 명확하게 구분하지는 못한다. 공부, 계속 공부...📝
자, 그럼 값을 따로 떼오는 것도 가능해졌으니 이제 작성시간도 포함시켜 POST할 수 있도록 해야한다.
다행히 기존 과제를 진행하며 Timestamped Class를 생성하여 작성 시간 및 수정 시간을 자동으로 받아오게끔 해두었다.
Timestamped
package com.sparta.week03.domain;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Timestamped {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime modifiedAt;
}
POST 결과2
이미 Entity Class에 Timestamped Class는 상속되어있고, 분명 H2에 찍어보았을 때는
자동으로 Column에 찍혀나오는 것 같았는데 이번에는 어째서인지 값을 전혀 받아오지 못하고 있었다.
이를 해결하기 위해서 또 얼마간의 구글링이 진행되었고, Entity Class에서의 선언이
추가로 이뤄져야 된다는 걸 알게되었다.
//Entity Class 내부에 추가
@CreatedDate
private LocalDateTime createdDate;
POST 결과3
발전은 있었으나 여전히 작성시간을 받아오지 못하였다.
몇 차례 구글링을 지속한 결과 추가 어노테이션이 필요하는 것을 알게되었다.
Entity Class 그리고 Application 모두에 추가
@EnableJpaAuditing
해당 어노테이션이 작성되어야 비로소 Jpa - Timestamped와의 연결이 가능해진다. |
POST 결과4
이렇게 하고나니 비로소 POST 결과에도 작성날짜가 제대로 출력되어 나왔다.
이제 남은 것은 GET에서도 작성시간을 받아오는 것.
나는 앞서 ResponseDto를 통해 GET을 통해 출력되는 데이터를 추려놓았기에 이 부분만을 수정할 필요가 있었다.
responseDto(2차수정)
package com.sparta.week03.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.time.LocalDateTime;
@AllArgsConstructor
@Data
public class PostResponseDto extends Timestamped{ //Timestamped를 상속받아오고
private String title;
private String username;
private LocalDateTime createdDate; //이 부분 추가
}
GET 결과3
드디어 원했던 목표했던 기능들을 모두 구현하였다.
그렇게 생각하지만 한 가지 큰 부분을 놓치고 있었다.
내가 작성한 Controller에서의 게시글 목록 조회 GET API 및 Repository는 게시글 배열을 가져오는 것이 아니라
게시글이 1개일 경우에만 띄워주는 API였다.
단일 게시글 조회 기능을 추가하기 위하여 API 테스트를 해보던 중, 게시글을 2개이상 작성 한 후 GET 요청을 하니
바로 오류가 출력되었다.
처음부터 새로운 방법으로 코드를 수정해야하나 고민하던 중 기존 코드와 내가 작성한 코드를 유심히 보고
몇 차례 코딩을 해보니 생각보다 간단하게 문제가 해결되었다.
내가 작성한 코드를 활용하여, 배열로만 받고 출력하면 되는 것이었다.
Controller(2차수정)
@GetMapping("/api/posts")
public List<PostResponseDto> readAllPost() {
return postRepository.findAllByOrderByModifiedAtDesc();
}
Repository(2차수정)
package com.sparta.week03.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface PostRepository extends JpaRepository<Post, Long> {
List<PostResponseDto> findAllByOrderByModifiedAtDesc();
}
GET 결과4
겨우 과제에서 요구한 7가지 기능들중 하나이지만 배운 부분이 정말 많았고, 내가 모르는 부분들을 너무나도 많이
발견할 수 있었다.
그리고 무엇보다 문제 해결 방법이 내가 완전히 몰랐던 코드를 추가하는 것이 아닌, 기존 코드에서 수정, 발전시키면
되는 부분이 많았다. 그렇기에 더욱 많이 배울 수 있었다.
조금 더 분발하자
'✍️개발로그' 카테고리의 다른 글
220830_실전프로젝트 8일차(feat.Item 수정부분 트러블슈팅🚀) (0) | 2022.09.03 |
---|---|
220829_실전프로젝트 4일차 (0) | 2022.08.29 |
20220823_클론코딩(항해인사이드) 5일차 (0) | 2022.08.23 |
20220820_클론코딩(항해인사이드) 2일차 (0) | 2022.08.20 |
20220726_개발로그(2)_특정게시글 조회(feat.Repository Method) (0) | 2022.07.26 |