스프링

[스프링] 공통 응답 형식 만들기 ResponseBodyAdvice

ImNM 2023. 3. 5. 21:38

 

 

위처럼 클라이언트와 협의하에 공통응답 형식을 어느정도 맞추고 시작하는 경우가 많다.

 

How to format response before sending in Nest.js?

I followed the documentation and was able to add an interceptor for response mapping. I want a consistent json format output for responses. How can I achieve this with interceptor or with something

stackoverflow.com

nestjs 에서는 공통으로 응답을 처리할 수 있는 부분이 있는데

스프링에서는 CommonResponse 같은 클래스를 만드셔서 사용하시는 분들이 많은것 같아서

ResponseBodyAdvice를 소개를 할려고 한다.

 


목차

1. 문제점

2. ResponseBodyAdvice

3. 적용하기


1. 문제점

 

딱히 문제점이라는건 아닌것같고 취향 차이인것같다.

@Getter
public class CommonResponse<T> {
    private int code;

    private boolean success;

    private T data;

    @Builder
    public CommonResponse(int code, boolean success, String message, T data) {
        this.code = code;
        this.success = success;
        this.message = message;
        this.data = data;
    }

    public static <T> CommonResponse<T> onSuccess(int code, T data) {
        return CommonResponse.<T>builder()
                .code(code)
                .success(true)
                .data(data)
                .build();
    }
}

위처럼 CommonResponse를 만들게 된다면,

모든 api 응답값마다 CommonResponse를 적어주게 될것이다.

 

간혹 누락할 수 있는 부분도 있을것같고, 공통의 코드들은 자연스래...

한번에 처리하고 싶은 욕구가 생긴다.


2. ResponseBodyAdvice

 

ResponseBodyAdvice (Spring Framework 6.0.6 API)

Allows customizing the response after the execution of an @ResponseBody or a ResponseEntity controller method but before the body is written with an HttpMessageConverter. Implementations may be registered directly with RequestMappingHandlerAdapter and Exce

docs.spring.io

ResponseBodyAdivce 를 통해서 해결할 수 있다.

public class SuccessResponseAdvice implements ResponseBodyAdvice {
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
        MediaType selectedContentType, Class selectedConverterType,
        ServerHttpRequest request,ServerHttpResponse response)
        
}

ResponseBodyAdivce 를 상속받고 

이중에서 beforeBodyWrite 를 오버라이드 해서

구현을 해주면 손쉽게 최종 응답값을 바꿀 수 있다.


3. 적용하기

@RestControllerAdvice(basePackages = "band.gosrock")
public class SuccessResponseAdvice implements ResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {return true;}
	
    @Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType,
        MediaType selectedContentType, Class selectedConverterType,
        ServerHttpRequest request,ServerHttpResponse response) {
        HttpServletResponse servletResponse =
                ((ServletServerHttpResponse) response).getServletResponse();

        int status = servletResponse.getStatus();
        HttpStatus resolve = HttpStatus.resolve(status);

        if (resolve == null) {
            return body;
        }

        if (resolve.is2xxSuccessful()) {
            return new SuccessResponse(status, body);
        }

        return body;
    }
}

@RestControllerAdvice(basePackages = "band.gosrock")

어노테이션을 달아주면 컨트롤러에 adivce를 적용할 수 있는데,

제일 중요한 점은 basePackages 라고 말하고 싶다.

 

두둥 프로젝트에서는 swagger로 문서화를 진행중인데

스웨거는 맨처음부터 그려서 내려주는 것이 아니라, api 목록들을 

/api/v3/api-docs 로 패칭해서 가져오기 때문에

basePackage를 명시해 놓지 않으면, 스웨거의 응답값 마져 

공통으로 응답형식을 바꿔져서 스웨거가 해석하지 못하게 된다.

 

따라서 꼭 basePackages 의 본인 패키지 정보를 명시해야한다.

 


 

 

GitHub - Gosrock/DuDoong-Backend: 모두를 위한 새로운 공연 라이프, 두둥!

모두를 위한 새로운 공연 라이프, 두둥! Contribute to Gosrock/DuDoong-Backend development by creating an account on GitHub.

github.com

모든 소스는 위에서 확인 가능하다.