Spring

ResponseEntity, RequestEntity, HttpEntity

teo_99 2023. 5. 1. 12:14

RequestEntity, ResponseEntity가 뭘까요?

 

일단 직접 코드를 열어봅시다.

// ResponseEntity.java
public class ResponseEntity<T> extends HttpEntity<T> {
	...
}
// RequestEntity.java
public class RequestEntity<T> extends HttpEntity<T> {
	...
}

두 객체 모두 HttpEntity를 상속받고 있네요.

그러면 HttpEntity의 개념을 먼저 알아 볼 필요가 있을 것 같습니다.

 

HttpEntity

공식 문서를 보게 되면, HttpEntity에 대한 설명으로 다음과 같이 나와 있습니다.

Represents an HTTP request or response entity, consisting of headers and body.

HTTP request와 response에 사용될 수 있는 객체이며, 헤더와 바디를 가지고 있다는 내용입니다.

 

그리고 이 HTTPEntity 가 언제 사용될 수 있는지에 대해서도 기술이 되어 있는데요, 다음과 같은 경우에 일반적으로 사용된다고 합니다.

  1. RestTemplate와 함께 사용
  2. Spring MVC의 컨트롤러에서 사용
RestTemplate란, HTTP 통신을 위해 정의된 템플릿으로 이를 통해 HTTP 프로토콜의 메소드를 쉽게 사용할 수 있습니다. 

 

 

public class HttpEntity<T> {

	private final HttpHeaders headers;

	@Nullable
	private final T body;
	
    ...
}

위 코드는 HttpEntity의 실제 구현부를 나타내는데요, 헤더와 바디를 제외하고는 별 다른 프로퍼티를 가지고 있지 않습니다. 따라서 HttpEntity를 단순하게 HTTP 통신을 위해 정의된 DTO 쯤으로 생각하면 편할 것 같습니다. 그럼 이제 이를 확장하는 RequestEntity와 ResponseEntity를 알아보러 가보죠.

 

RequestEntity

공식 문서에서는 다음과 같은 설명이 있네요.

Extension of HttpEntity that also exposes the HTTP method and the target URL. For use in the RestTemplate to prepare requests with and in @Controller methods to represent request input.

쉽게 말해 HttpEntity를 HTTP method와 target URL을 가질 수 있도록 확장시킨 버전이며, HttpEntity와 마찬가지로 RestTemplate나 Controller에서 요청을 보낼 때 사용될 수 있다는 것입니다. 그럼 이제 내부 코드를 보며 정말로 그런지 확인해보죠.

 

RequestEntity는 내부 프로퍼티가 다음과 같이 정의되어 있습니다.

public class RequestEntity<T> extends HttpEntity<T> {

	@Nullable
	private final HttpMethod method;

	@Nullable
	private final URI url;

	@Nullable
	private final Type type;
    
    ...
}

아까 설명한대로 HttpMethod와, url이 잘 정의되어 있네요. 그런데 여기서 type은 무엇을 의미할까요? type은 전송하는 데이터 객체의 클래스 유형을 지정합니다. 즉, body의 타입을 의미하는 것인데요. 만약 type이 String.class라면, body는 문자열 형식으로 전송되고, User.class라면 JSON 혹은 XML과 같이 직렬화된 상태로 전송됩니다. 이외의 프로퍼티는 이해하시는 그대로입니다. method는 HTTP method를 의미하며, url는 target URL을 의미합니다.

 

이외에도 RequestEntity는 여러 메소드를 제공하지만, 방금 설명한 프로퍼티와 HTTP의 기본 개념을 제대로 이해하고 있다면 자연스럽게 이해가 가능합니다. 즉, RequestEntity는 HttpEntity가 제공하는 헤더, 바디에 더불어 HTTP method, target URL, 바디의 타입까지 제공하는구나! 라고 요약할 수 있을 것 같네요. 

 

ResponseEntity

마찬가지로 공식 문서의 설명을 보면

Extension of HttpEntity that adds an HttpStatus status code. Used in RestTemplate as well as in @Controller methods.

HttpStatus Code를 추가적으로 제공하는 HttpEntity의 확장 버전이라고 나와 있습니다. 이 ResponseEntity는 응답할 때 사용되는데요, 이번에도 한번 코드를 뜯어보죠..!

 

public class ResponseEntity<T> extends HttpEntity<T> {

	private final Object status;

	...
}

status 이외에 다른 프로퍼티는 없네요. 그런데 왜 status 프로퍼티는 HttpStatus가 아닌 Object 타입으로 선언되었을까요? 그것은 raw한 status code도 받기 위함입니다. ResponseEntity의 생성자 중에는 다음과 같은 생성자가 존재하는데요,

 

public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, int rawStatus) {
    this(body, headers, (Object) rawStatus);
}

status code를 HttpStatus 열거형의 객체로 넘겨줄 수도 있지만, 404, 200과 같은 raw한 status code로도 넘겨줄 수 있도록 해 유연함을 제공하는 것입니다.

 

마찬가지로 위 내용을 이해했다면, 나머지는 모두 수반되는 내용들입니다. ResponseEntity도 요약하자면.. HttpEntity가 제공하는 헤더, 바디에 더불어 Status Code를 지정할 수 있구나! 라고 생각하시면 될 것 같습니다.

 

 

요약

ResponseEntity, RequestEntity, HttpEntity에 대해 학습했습니다.

 

HttpEntity는 Http 통신에 사용되는 객체로서, 헤더와 바디 정보를 담고 있었는데요, RequestEntity는 이에 더불어 URL, 바디 타입, HTTP method까지 지정이 가능했습니다. ResponseEntity는 상태 코드까지 지정이 가능했는데요. 세 객체 모두 일종의 데이터 교환을 위한 DTO라고 생각하면 될 듯 합니다. 다만 담고 있는 정보만 조금씩 다를 뿐이죠.

 


참고자료

https://tecoble.techcourse.co.kr/post/2021-07-25-resttemplate-webclient/