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 응답의 명시성을 향상시킨다.
이와 같이 추상화를 통해 코드의 명확성과 유지보수성을 향상시킬 수 있다.