Latte 개발일지 : 3. Querydsl 적용과 controller 개발

이동건·2021년 8월 13일
1

Latte

목록 보기
3/9
post-thumbnail

지난번에 Spring data JPA를 활용해 interview의 entity, repository, service를 제작하였다.
이번에는 해당 부분에 있어서 Querydsl을 적용해 리팩토링을 해 보고, controller까지 개발해보도록 한다.

인터뷰 부분에서 마음에 안 들었던 부분이 있다.

바로 이 부분을 Querydsl로 변경하여 좀 더 깔끔하게 바꾸어보겠다.

우선 Querydsl을 사용하기 위해 Custom Interface를 만들어주겠다.

그리고 이 인터페이스의 구현체 Impl class를 만들어준다. 네이밍은 꼭 Impl이 들어가주어야한다.

InterviewRepositoryCustom 인터페이스를 상속받았다. 커스텀 인터페이스의 메서드를 구현해주기 위해 우선 override한 메서드를 적어놓았다.

Querydsl의 4 버전을 사용하기 때문에 JPAQueryFactory를 만들어 주었다. 엔티티 매니저는 주입받아 사용하였다.

그럼 쿼리를 작성해보도록 한다.

우리가 원하는 것은 인터뷰 중에서 가장 최근의 인터뷰 하나만 가져오는 것이다.

다음과 같이 변경하자 엄청난 빨간줄이 생겼다.
우리가 원하는 건 하나의 인터뷰인데 반환 타입이 List이기 때문이다.
반환 타입을 Interview로 바꿔주도록 한다.

Custom interface와 해당 메서드의 반환 타입을 바꿔주었지만 related problem이 나타난다.
하지만 이는 예견된 결과이다. 왜냐? 우리는 테스트에서 List를 통해 받았기 때문이다.

테스트로 넘어가본다.

우리는 여기서 쓸데없이 List로 받은 후에 get을 이용해 꺼내고 있었다.
interviewRepositoryCustom을 interviewRepository가 상속받도록 추가해준 후

이제는 바로 Interview로 꺼내도록 바꾼다.

테스트를 돌려보자...
야호! 초록막대다!

전체 테스트도 돌려서 테스트 해 본다.

테스트가 통과되는 걸 보는 것은 언제나 행복하다.
유튜브에 보면 마음이 편해지는 영상, 편-안, 뭐 이런거 많은데 그 무엇도 이 테스트 통과 초록 막대를 이길 순 없을 것이다. (물론 지금은 별로 테스트가 없긴 하지만)

이제 querydsl로 원하던 코드를 리팩토링도 했겠다. 단숨에 controller를 개발하러 가 보자.

controller는 디자인 화면을 보면서 프론트가 어느 부분을 필요로 할지 생각하면서 제작하는 편이다.

우선 최상단의 인터뷰 제목, 내용을 가져오는 부분을 만들어보자.
만들기에 앞서 잠시 생각해보니 좋아요와 북마크, 해시태그를 같이 가져와야 하는가에 대한 의문이 들었다.
유저가 좋아요, 북마크 표시 등을 누르면 숫자가 바뀌니까 따로 만들어야하나?
그럴 경우에 위의 캐러셀 하나에만 4번의 네트워크 통신이 발생하게 된다.
이는 비효율적이라고 생각이 들었고 눌러서 숫자의 증감에 대한 부분 역시 프론트에서 실시간으로 가져오는 게 아니라 잠시 숫자 +1, 취소하면 -1을 한다는 생각을 한다면 굳이 따로 분리할 필요는 없을 거라는 생각이 들었다.
그래서 아예 carousel이라는 DTO를 하나 만들어 한 번에 넘겨주기로 하였다.

dto 패키지를 만든 후 CarouselDto 클래스를 만들어 주었다.

캐러셀이 필요한 내용인 인터뷰 아이디, 타이틀, 컨텐츠, 좋아요 갯수, 북마크 갯수, 인터뷰 해시태그, 나의 좋아요, 북마크 여부들을 넘기도록 구성하였다.

혹시 모를 추후의 확장에 대비해 다음과 같이 데이터를 감싸서 내보내기로 하였다.
또한 태그에 대한 부분은 따로 List를 이용해 전송하기로 하였다.

근데 제작하다보니 Tag 관련된 부분이 제작되지 않아 태그를 반환할 수 없는 상태이다.
우선 태그 부분부터 개발해주자.
인터뷰 게시글은 운영자가 직접 넣는 방식이기 때문에 createInterviewTag는 사용할 일이 없어 테스트는 패스하기로 하였다.
추후에 어드민 페이지가 개발된다면 그 때 추가적인 테스트 및 사용을 하게 될 것 같다.

우선 인터뷰 태그를 생성 할 수 있도록 테스트를 만들고 구현해 주었다.

그리고 인터뷰에 있는 태그들을 가져올 수 있도록 테스트를 만들고 구현해준다.

InterviewTag 부분에서 에러가 발생해 cascade 부분의 옵션을 추가해 주었다.
ManyToOne이 하나일 때는 괜찮았으나 양 다대일 두개가 합쳐지자 에러가 발생했다.
@OneToMany나 @ManyToOne 사용 시 부모 객체에 추가하는 자식 객체가 아직 db에 저장되지 않아 생긴 에러이다. 즉 영속성 전이를 해야한다.
cascade = CascadeType.ALL로 바꾸어주자 해결이 되었다.
(참고 : https://stackoverflow.com/questions/2302802/how-to-fix-the-hibernate-object-references-an-unsaved-transient-instance-save)

값이 잘 나타나는 걸 볼 수 있다.
하지만 도메인 이름과 도메인 속의 카테고리 이름을 똑같이 category라고 지어 헷갈리는 부분이 있었다.
도메인 속의 카테고리 또는 도메인 이름을 바꾸는 걸 고려할 필요가 있다.

이제 이어서 컨트롤러를 제작해 준다.

다음과 같이 원하는 데이터를 Dto에 담아 Result로 반환해 주었다.

컨트롤러가 자신의 권한을 넘어서는 동작을 하므로 해당 부분을 Service로 빼 주었다. 그와 동시에 DTO 역시 수정해 주었다.


여기서 한 번 더 정리해 준다.


코드가 훨씬 깔끔해졌다. 테스트 역시 전부 잘 통과하는 걸 확인했다.

http://localhost:8080/api/v1/interview/carousel?uid=1
요청 결과는 다음과 같이 나타났다.

이렇게 캐러셀 안의 데이터에 대한 api를 제작해 보았다.
이와 같은 방식으로 나머지도 진행할 것이며 이후의 포스트는 화면, 도메인 별로 유기적으로 나누어 업로드 하도록 하겠다.

profile
코드를 통한 세계의 창조

0개의 댓글