ResponseBodyAdvice

sseongeun·2024년 4월 14일

스프링

목록 보기
5/13

응답의 형태가 일관되지 못할때, 봉투에 담으면 어떨까?

그래서 도입된게, 봉투 패턴

📌 봉투 패턴이란?

  • Wrapper DTO를 만드는 방법

ex)

  • [Wrapper DTO - ApiResponse클래스]

    public class ApiResponse<T> {
    
        private final LocalDateTime timestamp = LocalDateTime.now();
        private String path;
        private T data;
        private String message;
    
        @Builder
        private ApiResponse(String path, T data, String message) {
            this.path = path;
            this.data = data;
            this.message = message;
        }
    }
  • [반환 형태]

    GET /api/performances/1
    
    {
      "timestamp": "2023-09-14T10:36:12.42831",
      "path": "/api/performances/1",
      "data": {
            "performanceId": 1,
            "title": "제4회 더 싱어즈 정기연주회",
            "duration": "2시간",
            "ageRating": 7,
            ...(생략)
        },
      "message": null
    }
  • [해당 방법의 단점]

    • 매번 dto를 ApiResponse로 한번 감싸줘야함
    • ApiResponse객체를 매번 생성해야함

그래서 출현한게, ResponseBodyAdvice

ResponseBodyAdvice란?

각 컨트롤러의 응답 데이터의 공통적으로 가공하고 싶은 요소가 있을 때 사용한다!

ex)
ResponseWrapper클래스 구현( ResponseBodyAdvice를 상속받음 )

@RestControllerAdvice(basePackages="패키지명") //Swagger가 해석할수있도록 패키지명을 명시해줘야함!
public class ResponseWrapper implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    //특정 응답에 대해 공통 처리를 할지 말지 결정
        return true;
    }

    @Override
    public Object beforeBodyWrite( //해당 컨트롤러의 모든 반환 데이터에 공통으로 처리하는 로직 담당하는 메서드
        Object body,
        MethodParameter returnType,
        MediaType selectedContentType,
        Class<? extends HttpMessageConverter<?>> selectedConverterType,
        ServerHttpRequest request,
        ServerHttpResponse response
    ) {
        String path = request.getURI().getPath();

        if (body instanceof ErrorData errorData) {
            ExceptionRule exceptionRule = errorData.getExceptionRule();
            response.setStatusCode(exceptionRule.getStatus());

            return ApiResponse.builder()
                .path(path)
                .data(errorData.getRejectedValues())
                .message(exceptionRule.getMessage())
                .build();
        }

        return ApiResponse.builder()
            .path(path)
            .data(body)
            .build();
    }
}
profile
공부 기록...

0개의 댓글