GPT 에게 한 질문

- 왜 service 계층에서 다시 controller 계층으로 Entity 자체를 넘기는 행위를 지양 해야하는가?

 

GPT 답변
  1. Lazy Loading 문제: Entity는 연관된 다른 Entity를 가지고 있을 수 있습니다. 이 경우, Controller에서 Entity를 반환하면 JSON으로 직렬화할 때 Lazy Loading 문제가 발생할 수 있습니다. 이는 연관된 객체를 가져오기 위해 추가적인 데이터베이스 쿼리가 발생할 수 있으며, 이는 성능에 부정적인 영향을 줄 수 있습니다.
  2. API 설계의 일관성: Entity는 데이터베이스 스키마를 나타내는데 사용되므로 API 응답의 형태로 적합하지 않을 수 있습니다. 또한 Entity는 비즈니스 로직을 담지 않고 있는 경우가 많으므로 API의 일관성을 유지하기 어려울 수 있습니다.

 

 

 

  • @CreatedDate
    • 데이터 저장 시간 자동 업데이트
  • @LastModifiedDate
    • 마지막 수정 시간 자동 업데이트

기본적인 테스트 방법


  • @SpringBootTest Annotation
    • 해당 Annotation을 쓰면, @Autowired 를 통해 별도의 의존성 주입 없이 테스트에 필요한 객체를 가져다 쓸 수 있다.
      • AccountService는 AccountRepository 를 주입받고 있기 때문에 연쇄적으로 의존성을 주입해줄 필요 없음.
  • @DisplayName()
    •  테스트 목록에 표기 되는 이름을 원하는 이름으로 변경해줄 수 있다.
  • @BeforeEach
    • 하위의 테스트들을 실행하기 전 먼저 실행 해주는 로직으로 간편하게 초기값을 세팅해줄 수 있다.
      • ex) 테스트 1의 계좌를 먼저 생성해 id 값 1을 준다.
      • ex) 테스트 2의 계좌를 먼저 생성해 id 값 2를 준다.
      • BeforeEach 가 없다면 여러개의 테스트에 계좌를 생성하는 로직을 모두 포함 시켜줘야함.

Mockito 로 테스트 방법

 

  • @ExtendWIth(MockitoExcention.class)
    • Mockito 사용을 위한 Annotation
    • @Mock
      • 주입 시켜야할 Mock 만들기
    • @InjectionMocks
      • 위에서 만든 Mock 을 해당 객체에 주입 하기

이후 해당 Mock을 통한 테스트 진행 가능


WebMvcTest 로 Controller 테스트 하는 모습

 

유틸리티 클래스의 기본 모습

  • 유틸리티 클래스란 ?
    •  주로 정적(static) 메서드로만 이루어진 클래스를 뜻한다.
      • 객체의 생성 없이 사용 가능
      • 특정 작업을 수행하는 메서드를 제공 (여러곳에서 반복적 사용이 가능)
      • 인스턴스화 방지, 인스턴스 생성이 필요 없기 때문에 유틸리티 클래스의 생성자는 private 으로 선언 되거나 클래스를 final로 선언하여 상속을 막는다.
  • @UtilityClass Annotation
    • 유틸리티 클래스를 간편히 사용할 수 있게 해주는 Annotation
      • 생성자를 기본 private으로 설정 해준다.
      • 모든 메서드를 static 으로 자동 설정해준다. (위의 예시에서는 static이 쓰여있다. 읽는 이로 하여금 더 명확한 표현 제공을 위해 적어두었지만 UtilityClass Annotation을 사용 할 경우 적지 않아도 무방하다.)
      • final 클래스로 만들어 상속을 막아준다.
      • 클래스에 대한 기본 생성자를 생성하지 않으므로, 코드가 더 간결해진다.

Interceptor 의 기본 형태

HadlerInterceptor 를 구현한 Interceptor 의 모습

 

  • HandlerInterceptor 를 구현해 필수 메서드들을 재정의 한다.
    • preHandle 는 반환 값이 boolean 이다.
      • 실제 요청 전에 검증을 위한 메서드로 검증 실패시 false 를 반환해 다음 Interceptor 로 연결이 되지 못한다.
      • true 를 반환 할 경우, 다음 Interceptor 로 연결 되거나 해당 요청을 처리 해줄 Handler (MVC 에서의 Controller) 로 연결 해준다.

addInterceptor

WebConfig 클래스에 WebMvcConfigurer 를 구현 한다.

  • WebMvcConfigurer 를 구현
    • addInterceptores 를 재정의 한다.
    • 위와 같이 정의 해놓은 커스텀 Interceptor(현재는 LogInterceptor) 를 추가 해준다.

doFilter 메서드

 

FIlter의 사용 예제

 

  • 필터는 FilterChain 인터페이스가 사용 된다.
    • FilterChain 인터페이스는 doFilter 메서드를 담고 있다.
      • doFilter 메서드는 현재 필터가 다음 필터로 제어를 전달하는 역할을 해준다. 따라서 현재 필터가 끝나면 다음 필터로 제어를 전달 하며, 다음 필터가 존재하지 않는다면 요청을 처리하는 서블릿으로 제어를 전달 한다.

때문에 Filter 를 사용 한다면 doFIlter 메서드는 필히 구현 해줘야 한다.

 


커스텀 핸들러를 통한 Filter 운용

Filter 를 핸들러를 통해 이용하는 모습

  • 필터는 개별적으로 사용되기 보다 이 처럼 커스텀 핸들러를 통해 한 곳에서 운용 되는 것이 컨벤션적이다.
    • 여러 필터를 한 곳에서 운용해 보다 유연한 구성이 가능하다.

+ Recent posts