
내일배움캠프 20일차 TIL : Spring - RequestEntity
벌써 20일차 TIL이다.
https://github.com/WonGi-Kim/spring_personal_project1
개인 과제 피드백을 받으면서 ResponseEntity를 사용하면 Http응답을 다양하게 제어할 수 있다고 하였기에 사용해보고 사용하기 위해 공부했던 내용을 간단하게 적어보려 한다.
Spring Framework에서 제공하는 클래스 중 HttpEntity클래스를 상속받아 구현한 클래스다.
RequestEntity, ResponseEntity가 존재하며
ResponseEntity는 사용자의 HttpRequest에 대한 응답 데이터를 포함하는 클래스이다.
따라서 HttpStatus, HttpHeaders, HttpBody를 포함한다.
일반적으로 Controller에서는 객체를 Return하게 되는데 객체가 Return될 경우 Http응답을 제어할 수 없다.
Restful API를 작성한다면 클라이언트와 서버 간의 통신에 필요한 정보를 제공해야 하며,
Http Status code와 Header, Body를 제공하며 서버 통신을 다양하게 할 수 있기 때문에 사용한다.
ResponseEntity는 this()를 통해서 매개변수가 3개인 생성자를 호출해 객체를 생성한다.
위에서 HttpStatus, HttpHeaders, HttpBody를 포함 한다고 했기 때문에 3가지를 담을
ResponseEntity를 생성해준다.
public class CustomResponse<T> {
private int code; // 응답 코드
private String message; // head에 들어갈 메시지
private T body; // 넘겨줄 객체, body
}
여기서 응답 코드를 위해 Enum을 생성해 코드와 메시지를 담을 수 있도록 한다.
public enum StatusEnum {
OK(200, "OK"),
BAD_REQUEST(400, "BAD_REQUEST"),
NOT_FOUND(404, "NOT_FOUND"),
INTERNAL_SERER_ERROR(500, "INTERNAL_SERVER_ERROR");
int statusCode;
String statusMessage;
StatusEnum(int statusCode, String statusMessage) {
this.statusCode = statusCode;
this.statusMessage = statusMessage;
}
public int getStatusCode() {
return statusCode;
}
public String getStatusMessage() {
return statusMessage;
}
}
이제 ResponseEntity에 넘겨줄 코드와 메시지, 바디까지 완성이 되었으면 ResponseEntity에 값을 넣어 리턴시키면 된다.
private CustomResponse setHttpStatus(ToDoResponseDto responseDto) {
int statusCode = StatusEnum.OK.getStatusCode();
String message = StatusEnum.OK.getStatusMessage();
CustomResponse<ToDoResponseDto> customResponse = new CustomResponse<>();
customResponse.setCode(statusCode);
customResponse.setMessage(message);
customResponse.setBody(responseDto);
return customResponse;
}
코드를 살펴보면 Enum에서 받아오는 getStatusCode, getStatusMessage 그리고
Service 레이어에서 반환받은 객체인 responseDto를 ResponseEntity에 body에 할당해준다.
일반적으로 ResponseEntity 로 Return할 때는 생성자 패턴보다는 빌더 패턴을 사용한다.
public ResponseEntity<CustomResponse<ToDoResponseDto>> updateToDo(@PathVariable Long id, @RequestBody ToDoRequestDto toDoRequestDto) {
ToDoResponseDto responseDto = toDoListService.updateToDo(id, toDoRequestDto);
return ResponseEntity.ok(setHttpStatus(responseDto));
}
그리고 위의 과정으로 Controller에서 ReponseEntity를 반환하여 HTTP응답을 다양하게 처리할 수 있다.
ResponseEntity는 타입을 명시하지 않을 경우 Object타입을 리턴하기 때문에 크게 문제가 발생하지 않을 수 있지만 대부분의 상황에서는 유지보수를 위해 타입 명시를 권장한다.
다만 여러개의 타입을 반환할 경우 Object를 명시하거나 와일드카드를 사용하여 리턴타입을 지정해주는 것이 좋다.
출처