개발 일기

[Spring Boot] @ResponseBody와 ResponseEntity 비교 본문

Back-End/Spring

[Spring Boot] @ResponseBody와 ResponseEntity 비교

개발 일기장 주인 2024. 9. 19. 23:51

예외 처리 관련한 블로그를 보다가 Controller에서 응답값 즉, Spring에서 HTTP 통신 시 ResponseBody에 메세지를 설정하는 방식에 두 가지의 처리 방식이 있는 것 같았고 그 두 가지인 @ResponseBody와 ResponseEntity 비교해보고 둘 중 무엇을 선택하는 것이 좋을지 알기 위해 정리해보게 됐다.


@ResponseBody (+ Response DTO)

@GetMapping("/test")
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public MemberInfoResponseDto responseTest(Long memberId) {
    ...
    return memberInfoResponseDto
}
  • @ResponseBody는 HTTP 규격에 맞는 응답을 만들어주기 위한 Annotation.
  • 해당 어노테이션을 통해 컨트롤러가 데이터를 반환할 때 HttpMessageConverter를 사용해서 자바 객체를 응답 본문(body) 메시지를 만들어 반환하게 된다.
  • @RestController 를 사용하면 자동으로 모든 핸들러 메소드에 @ResponseBody 가 적용

@RestController에 포함된 @ResponseBody

하지만 단점으로는 HTTP 규격 구성 요소 중 하나인 Header 에 대해서 유연하게 설정을 할 수 없고  HttpStatus도 메서드 밖에서 Annotation을 사용하여 따로 설정을 해주어야한다.

이는 @ResponseBody를 사용하면 HTTP 응답에서 바디 부분에만 응답 객체를 직렬화하여 포함시키기 때문이다.

이와 같은 점들을 해결해 줄 수 있는 것이 ResponseEntity 라는 객체이다.


ResponseEntity<T>

@GetMapping("/test")
public ResponseEntity<MemberInfoResponseDto> responseTest(Long memberId) {
    ...
    return new ResponseEntity<MemberInfoResponseDto> (
            memberInfoResponseDto, //HttpBody 설정
            headers,     // HttpHeader 설정
            HttpStatus.valueOf(200) // HttpStatus 설정
    )
}
  • ResponseEntity 도 마찬가지로 HTTP 응답을 빠르게 만들어주기 위한 객체
  • @ResponseBody와는 다르게 ResponseEntity<T>를 사용하면 DTO 객체 반환 시보다 설정할 수 있는 부분이 더 추가된다.

  • ReponseEntity<T>는 HttpEntity<T>를 상속받기 때문에 HttpStatus 뿐만아니라 HttpHeader, HttpBody를 설정하여 HTTP 응답을 보낼 수 있다.
반면에, @ResponseBody와 객체를 사용해서는 위의 옵션을 설정하기 힘들다. HTTP 상태 코드는 @ResponseStatus를 통해 설정해줄 수 있지만, 헤더 부분은 설정하기가 힘들다.

 

위에서 처럼 new 키워드 즉, Constructor를 통해 ResponseEntity를 생성하기 보다는 아래와 같이 Builder를 사용하는 것을 권장한다.

 숫자로 된 상태 코드를 넣을 때, 잘못된 숫자를 넣을 수 있는 실수 때문이라고 한다.

  return ResponseEntity.ok()
        .headers(headers)
        .body(MemberInfoResponseDto);

어떤 것을 선택하는 것이 좋은가?

  • ResponseEntity<T>의 단점은 @ResponseBody 보다 코드량이 많아진다 정도인 것 같은데 그렇다고해도 생산성에 있어도 그렇게 차이 있지는 않다.
  • @ResponseBody는 단순히 응답 본문만 직렬화하여 반환하기 때문에, 나중에 HTTP 응답에 헤더나 상태 코드와 같은 추가 설정이 필요할 경우, 해당 메소드도 수정해야 하는 단점

➜ HTTP 상태코드, 바디, 헤더 등 커스텀 할 수 있는 ResponseEntity<T> 를 사용하는 것이 좋을 것 같다.