본문 바로가기
Back-end/카카오테크캠퍼스

[카카오테크캠퍼스] 3주차 과제 코드리뷰 정리

by 잔디🌿 2024. 9. 3.

    내 질문

    Q1

    실제 기능에서는 getter가 필요하지 않는데, 테스트를 위해서는 필요한 경우가 있다. 이 때 테스트를 위해서 보안을 조금 포기하더라도 getter을 만드는 것이 좋은지 궁금합니다.

     

    A.

    필요하면 만들어야하긴하지만, 값을 꼭 꺼내어 확인해야하는지 고민해보아야한다. 특히 값이 바뀌는 것에 대한 테스트는 굳이 필요하지 않을수도 있기 때문이다. 

     

    Q2

    이번 작업과 같이 한 도메인에서 특정 기능을 만들 때 commit를 도메인 단위로 하는게 좋은지 아니면 controller, service단위로 하는지 궁금합니다.

     

    A.

    commit는 문제가 발생했을 때 롤백 지점을 쉽게 잡기 위한 포인트읻. 나중에 "이쯤에서 롤백하면 되겠네"가 편하도록 단위를 정하자

     

    피드백

    equlas, hashcode로 동등성을 부여하자

    나는 동등성에 대한 개념을 잘 몰랐었다

     

    동일성이란 두 객체의 메모지 주소와 값이 모두 같은 것이고

    동등성이란 두 객체의 값이 같은 것이다.

     

    java에서 동일성은 ==로, 동일성은 equals로 확인이 가능하다

     

    영속성 컨텍스트와 objectMapper와 같이 중복된 값들을 저장하지 않는 저장소에 동일한 객체를 넣으면 덮어쓰기 된다.

     

    따라서 특정 값이 같으면 같은 객체로 인식하게 만드는 기능이 필요할 때가 있다. 이를 위해서 equals와 hashcode로 동등성을 부여해주어야한다.

     

    presentation계층이 domain계층에 의존하게 하지 않는다.

        public static WishList MapWishListRequestToWishList(WishListRequest wishListRequest){
            return new WishList(wishListRequest.memberId(),wishListRequest.menuId());
        }
    
        public static WishListResponse MapWishListToWishListResponse(WishList wishList){
            return new WishListResponse(wishList.id, wishList.menuId);
        }

    나는 위와 같은 코드를 엔티티 내에 넣었었다. 

    하지만 이렇게 하면 presentation계층에 domain계층이 의존한다고 하셨다. 이렇게 하면 양방향 의존이라 좋지 않다.

    그래서 위 코드를 service 계층으로 옮겼다.

     

    주석 제거를 잘하자

    으악 이건 내 실수다. 앞으로 pr 날리기 전에 기본적인거 다 체크했는지 확인하고 올려야겠다.

     

    data jpa test 활용을 잘했다! 느낀 점이 있다면?

    이건 내가 라이브특강 때 배워서 적용해보았다.

    data jpa test는 jpa만을 테스트하기 위한 어노테이션이다.

    메모리 상에 내부 데이터베이스를 생성하고, @Entity 클래스들을 등록하고, JPA Repository 설정들을 해준다. 각 테스트마다 테스트가 완료되면 관련한 설정들은 롤백된다.

     

    자동으로 롤백된다는 것이 테스트와 실제 프로젝트를 분리할 수 있어 큰 장점인 것 같다!

     

    회원가입을 할 때에는 토큰을 반환하지 않아도 된다

    나는 사실 postman을 활용하여 테스트할 때 회원가입과 동시에 토큰을 받을 수 있으면 바로 인증이 필요한 기능을 테스트 할 수 있어서 회원가입을 담당하는 controller에서 토큰을 반환하도록 했는데 불필요했던 것 같다.

    살짝 번거롭더라도 로그인 기능에서만 토큰을 반환하도록 수정하였다.

     

    Repository는 Service계층에서 의존하도록 하자

    원래 코드에서는 Controller에서 Repository를 주입받아서 사용하는 부분이 있었다. 

    나는 해당 도메인에 대한 repository가 아니라서 괜찮다고 생각했는데 모든 Repostory는 Service 계층에서 의존하도록 하는게 좋다고 하셨다.

     

    발생한 에러를 그대로 보내는 것 보다 지정된 메세지를 보내자.

    기존에는 발생한 에러를 그대로 전달하였다. 하지만 이렇게 하면 보안상 좋지 않다고 하셨다. 그래서 발생한 에러를 "에러가 발생했습니다 관리자에게 문의해주세요"와 같은 메세지로 전달하는 것으로 바꾸었다.

     

    DTO는 데이터 전달의 역할만 하도록 하자

    나는 보안상의 이점이 있어 클라이언트와 정보를 주고 받을 때 엔티티로 객체로 주고받지 않고, Recode를 사용한 DTO를 주고 받았다.

    클라이언트로부터 데이터를 받는 과정에서 이 유효성을 검증하기 위해서 @Valided로 검증 로직을 넣어두었다. 그런데 멘토님께서 이렇게 하는 방식보다는 DTO는 데이터 전달의 역할만을 하는 것을 추천한다고 하셨다.

     

    그래서 이를 해결하기 위해서 VO를 만들었다. VO는 엔티티와 다르게 id가 없고 필드가 하나이다.

    그래서 엔티티에 들어가는 하나의 필드를 VO로 만들어서 VO 내에 검증 로직을 넣는 방식을 추천해주셨다. 실제로 이렇게 바꾸었더니 코드가 전체적으로 깔끔해진 것이 느껴졌다.

     

    Optional 쓰기

    optional을 사용하면 값이 null일 때에도 새로운 무언가로 매핑이 가능하고, 바로 예외 던지는 것도 가능하다. 

     

    인터페이스에는 @Repository를 생략해도 된다.

    이 부분이었는데, JpaRepository에 이미 @Repository 어노테이션이 등록되어있어서 생략해도 된다고 하셨다.