전체 보기
🍀

ResponseBody, ResponseEntity, RestController 사용과 추상화

작성일자
2024/04/19
태그
DIARY_DEVELOP
프로젝트
WoowaCourse
책 종류
1 more property
happy case만 처리하고 전부 status code로 200을 뱉을 때, 아래 4개의 코드는 같은 결과를 낸다.
// 1번 (현재 방식) @Controller public class ReservationController { @GetMapping public ResponseEntity<List<ReservationFindAllResponse>> findAllReservation() {
Java
복사
// 2번 @Controller @ResponseBody public class ReservationController { @GetMapping public List<ReservationFindAllResponse> findAllReservation() {
Java
복사
// 3번 @RestController // @RestController = @Controller + @ResponseBody public class ReservationController { @GetMapping public List<ReservationFindAllResponse> findAllReservation() {
Java
복사
// 4번 @RestController // @RestController = @Controller + @ResponseBody public class ReservationController { @GetMapping public ResponseEntity<List<ReservationFindAllResponse>> findAllReservation() {
Java
복사

Controller vs RestController

우선 1,2번보단 3,4번을 사용하는 편이 현재 코드의 의도를 더 명확히 드러낼 수 있다 생각한다. Restful한 웹 서비스를 생성할 거라는걸 이름만으로도 표현해주기 때문이다. 참고
Spring 4.0 introduced the @RestController annotation in order to simplify the creation of RESTful web services

ResponseBody vs ResponseEntity

다음으로 3번보단 4번을 사용하는 편이 추상화 관점에서 더 바람직하다 생각한다. 추상화 레벨을 통일하는 데 도움이 되기 때문이다.
자동차 경주 프로그램에서 자동차의 움직임 여부를 결정할 때 IntGenerator를 사용하는 것보단 PowerGenerator를 사용하는 편이 더 추상화 레벨이 통일된다. 단순히 클래스 이름만 Int~에서 Power~로 바꿔졌을 뿐인데 Single Level of Abstraction 원칙에 부합해졌다.
마찬가지로 RestController에서도 단순히 ReservationDTO를 사용하는 것보단 ReservationResponse 를 사용하는 편이 더 추상화 레벨이 통일된다. 응답값임을 나타내는 주는 것이다. 더 나아가, ResponseEntity<ReservationResponse> 를 사용한다면 API의 응답값임을 나타내줌으로써 추상화 레벨을 더욱 통일해줄 수 있다.

추상화

header를 포함하여 API의 응답을 관리하는 방식도 추상화 관점에서 설명할 수 있다. 1번 코드를 2번 코드로 리팩토링해보았다.
// 1번 @Controller public class ReservationController { @PostMapping("/reservations") @ResponseStatus(HttpStatus.CREATED) @ResponseBody // 3.0에 등장 public String saveReservation(HttpServletResponse response) { String resourceLocation = "/resources/123"; response.setHeader("Location", resourceLocation); return ""; } }
Java
복사
// 2번 @RestController // 3.2에 등장 public class ReservationController { @PostMapping("/reservations") public ResponseEntity<Void> saveReservation() { return ResponseEntity.created("/resources/123"); // 3.1에 등장 } }
Java
복사
주요 변경 사항에 대해 정리하자면 아래와 같다.
@ResponseBody와 함께 @Controller를 사용하는 대신, @RestController를 사용하여 응답 본문이 자동으로 처리되게 한다.
ResponseEntity를 사용함으로써 HTTP 응답 코드와 헤더를 더 선언적으로 관리할 수 있다. 이는 HttpServletResponse를 직접 조작하는 것보다 추상화 수준을 높여주며, API 응답의 명시성을 향상시킨다.
이와 같이 추상화를 통해 코드의 명확성과 유지보수성을 향상시킬 수 있다.