[RestAPI] ResponseEntity 자세히 알아보기 (feat. 상태코드)
프로젝트로 restAPI를 개발하다보니 응답에 간단한경우 @ResponseBody를 쓰지만 HTTP header
라던지 상태코드 제어
등 HTTP 스펙을 다뤄야하는 경우가 훨씬 많아 ResponseEntity를 쓰게 되는 경우가 훨씬 많다.
상태코드 차이
@ResponseBody의 경우 @ResponseStatus(HttpStatus.OK)로 따로 상태코드를 다뤄줘야 하는데 조건별로 응답 상태코드가 다른경우 번거롭다.
@ResponseBody @ResponseStatus(HttpStatus.OK) //상태코드 지정 public MoveResponseDto move(@PathVariable String name, @RequestBody MoveDto moveDto) { ... return moveResponseDto; }
반면에 ResponseEntity
는 하나객체로 응답을 다루기 때문에 조건별로 응답 상태코드가 다른경우에도 문제없다. public ResponseEntity<MoveResponseDto> move(@PathVariable String name, @RequestBody MoveDto moveDto) { ... return new ResponseEntity<MoveResponseDto>(moveResponseDto, headers, HttpStatus.valueOf(200)); // ResponseEntity를 활용한 응답 생성 }
글을 읽기에 앞서 공식문서를 함께 참조하자
ResponseEntity
상태코드 + HTTP body + HTTP header를 포함해 하나의 객체로 만들어 준다.
응답 HTTP로 변환될 정보를 모두 담은 요소들을 객체로 만들어서 반환
스프링이 HTTP로 변환해서 클라이언트에서 response한다.
구조 살펴보기
ResponseEntity는 스프링이 HTTP를 다루기위해 제공하는 HttpEntity를 상속 받고있다.
RequestEntity도 있다.
//ResponseEntity 선언 구조
public class ResponseEntity extends HttpEntity {
private final Object status; //Status를 필드값으로 가지고있음.
...
}
HttpEntity를 보면 HTTP header 와 body를 필드로 가지고있다.
//HttpEntity 선언 구조
public class HttpEntity<T> {
public static final HttpEntity<?> EMPTY = new HttpEntity<>();
private final HttpHeaders headers; //HttpHeaders -> header를 설정하는데 사용하는 클래스
@Nullable
private final T body; //제너릭으로 바디에 들어갈 객체를 받음 -> HttpMessageConverter
}
body가 제너릭으로 선언되어있음을 인지하자
즉, ResponseEntity 는 HttpEntity 를 상속하고있기 때문에 상태코드 + HTTP body + HTTP header를 모두 설정해 하나의 객체로 만들수 있다,
객체 생성하기 Constructor vs Builder
Constructor
공식문서를 살펴보면 여러개의 Constructor(생성자)가 있음을 알수있다.
위 구조에서 살펴보았듯이 ResponseEntity는 바디,헤더,상태코드를 설정해서 생성할수있다.
Constructor 를 활용하여 ResponseEntity 를 사용한 예시는 다음과 같다
주로 Body , Header , StatusCode 를 차례로 입력하는 Constructor를 사용한다
public ResponseEntity<MoveResponseDto> move(@PathVariable String name,
@RequestBody MoveDto moveDto) {
//header data
HttpHeaders headers = new HttpHeaders();
headers.set("Game", "Chess");
String command = makeMoveCmd(moveDto.getSource(), moveDto.getTarget());
springChessService.move(name, command, new Commands(command));
//body data
MoveResponseDto moveResponseDto = new MoveResponseDto(springChessService
.continuedGameInfo(name), name);
return new ResponseEntity<MoveResponseDto>(moveResponseDto, headers, HttpStatus.valueOf(200)); // ResponseEntity를 활용한 응답 HTTP 생성
}
Builder
ResponseEntity 를 사용할 때, Constructor 를 사용하기보다는 Builder 를 활용하는 것을 권장한다.
//Constructor
return new ResponseEntity<MoveResponseDto>(moveResponseDto, headers, HttpStatus.valueOf(200));
//Builder
return ResponseEntity.ok() //상태코드 메서드
.headers(headers)
.body(moveResponseDto);
차이라면 Constructor는 상태코드 수를 직접 입력하는데 반해 Builder는 Builder가 제공하는 메서드 ok()를 이용해 상태코드를 설정했기 때문이다.
Builder가 제공하는 메서드를 이용해 ResponseEntity 객체를 구축함으로써 좀더 이해하기도 쉽고 상태코드 value를 잘못 넣는 일을 방지하는 등 실수를 줄일 수 있기 때문이다.
정리
ResponseEntity를 사용하면 Body , Header , StatusCode 를 설정한 응답 HTTP를 쉽게 생성해서 응답할수있다.
Reference
https://tecoble.techcourse.co.kr/post/2021-05-10-response-entity/
'개발 일지 > RestAPI' 카테고리의 다른 글
[restAPI] 응답 헤더 다루기 (0) | 2022.01.20 |
---|---|
[RestAPI] CORS (Cross Origin Resource Sharing) (0) | 2022.01.19 |
[RestAPI] ResponseEntity<T> , @ResponseBody 로 응답 HTTP 다루기 (0) | 2022.01.19 |
[RestAPI] HTTP 상태코드 (0) | 2022.01.19 |
[RestAPI] HTTP header (0) | 2022.01.19 |