인증 인가 기능이 완료되었으므로 이제 인증 인가 기능을 활용할 차례다. 인증 인가 기능의 마지막에 리뷰 작성의 경우 반드시 유효한 토큰이 있어야만 작성할 수 있도록 설정했는데, 여기서 가져온 회원 정보로 리뷰와 연관관계를 맺어주는 작업을 진행했다.
@Entity
@Table(name = "review")
@EntityListeners(AuditingEntityListener.class)
@Getter
public class Review {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member member;
...
}
이 때 우리끼리 정한 규칙에 따라 @ManyToOne
의 로딩 방식을 FetchType.LAZY
로 설정해줬다. 다만 고려해볼만한 부분은 현재 사실상 리뷰를 조회하는 기능에서는 무조건 Member
정보도 가져와야 한다는 점인데, 이렇게 하면 지연 로딩을 쓰는 의미가 없는 것 같고 오히려 N+1 문제만 발생하기 때문에 별로일 것 같지만, 지연 로딩으로 설정할 필요가 있다. 지연 로딩 시에도 id 값만 사용할 때는 프록시 객체 초기화가 안되기 때문에, 리뷰 삭제 기능을 생각하면 지연 로딩으로 설정해 두는 편이 좋다. 이후 서비스 레이어에서 리뷰와 회원을 매핑하는 로직을 작성했다. 또한 연관관계를 새로 맺어줌에 따라 조회 시 연관관계도 함께 조회하여 리뷰에 작성자 정보를 매핑하는 로직도 작성했다.
이렇게 리뷰 작성 시에 로그인한 회원과 연관관계를 맺어주고, 조회 시에는 DTO에 작성자 정보를 함께 담도록 하는 기능을 구현했는데, 시간이 모자라 리뷰 수정과 삭제 기능을 완성하지 못한 것은 조금 아쉽다.
DTO에는 equals / hashCode를 재정의 하지 않았다. 대신 Assertions
의 동등성 비교 메서드를 활용했다.
assertThat(keyboardResponse).usingRecursiveComparison()
.isEqualTo(KeyboardResponse.from(keyboard));
그런데 List에 들어가 있는 경우가 애매했다. 예를 들어 List<ReviewResponse>
에 특정 response들이 들어있는지 확인해야 하는 경우, usingRecursiveComparison
으로는 객체끼리 동등성밖에 비교 못하므로 컬렉션 내부 값을 비교할 수 없었다. 그래서 궁여지책으로 extracting
으로 id값만 뽑아서 테스트하고 있었는데, 문제는 작성자 정보가 추가되면서, 작성자가 제대로 매핑되어있는지 확인할 필요가 있었다는 것이다. 그래서 리스트 내부의 값들이 포함되어 있는지를 동등성 비교로 하는 방법이 없을까 하고 Assertions
의 메서드들을 뒤져봤는데, 결국 찾아냈다. usingRecursiveFieldByFieldElementComparator
를 통해 할 수 있었다.
assertThat(reviewPageResponse.getItems()).hasSize(2)
.usingRecursiveFieldByFieldElementComparator()
.containsOnly(ReviewResponse.from(review1), ReviewResponse.from(review2));
이렇게 하면 equals / hashCode를 재정의 했을 때의 containsOnly
와 동일한 결과를 보장할 수 있었다.
GitHub OAuth QA 과정에서 버그를 발견했다. OAuth 로그인의 응답을 JSON 형태로 받아오려고 했는데, 실제로 넘어오는 값은 한 줄 짜리 string이었다. 확인해보니 HTTP response header가 x-www-urlencoded
형식이었다. 다행히도 GitHub OAuth 문서를 확인해보니 x-www-urlencoded
, application/json
, application/xml
의 세 가지 형태로 받아올 수 있었다.
공식 문서에 따르면 Accept
헤더에 값을 주어서 받아올 형식을 선택할 수 있다고 나와 있어서, WebClient
를 사용하는 부분에 .accept(MediaType.*APPLICATION_JSON*)
한 줄을 추가해주어 해결했다.
오늘 구현하지 못한 리뷰의 수정 및 삭제 기능을 인증 인가와 연계해서 처리하는 것이 목표다.