[Spring] RestController vs. Controller

Kim Hyen Su·2024년 3월 29일
0

Spring

목록 보기
2/13
post-thumbnail

🌿 Spring

Index

프로젝트 진행 중 문득 RestController와 Controller의 차이점에 대해 고민하게되었습니다. 우선, 두 어노테이션의 큰 차이점은 반환값이 다르다는 점입니다.

Controller에서 반환하는 것은 보통 HTTP Response를 의미합니다. 즉, @Controller와 @RestController 간의 주요 차이점은 HTTP Response Body가 생성되는 방식입니다.

@Controller

전통적인 Spring MVC의 컨트롤러인 @Controller는 주로 렌더링된 HTML 페이지를 반환합니다. 일반적인 MVC는 다음과 같은 과정을 통해서 Client에게 View(HTML 페이지)를 반환해줍니다.

  1. Client로 부터 URI 형식으로 웹 애플리케이션에 요청을 보냅니다.

  2. DispatcherServlet에서 요청을 처리할 대상을 찾습니다.

  3. HandlerAdapter를 통해서 요청을 Controller에 위임합니다.

  4. Controller는 요청을 Buisiness Logic을 거쳐 처리한 뒤 가공된 데이터와 View Name을 ModelAndView 객체에 담아 반환해줍니다.

  5. DispatcherServlet은 ViewResolver를 통해서 ViewName에 해당하는 View를 찾아서 클라이언트에게 반환해줍니다.

Controller를 통해서 Body에 Data 반환하기

Spring MVC 컨트롤러 사용 시 Data를 직접 반환해야 하는 경우도 많습니다. 이를 위해 @Controller에서는 @ResponseBody 어노테이션을 사용하여 Json 데이터를 반환할 수 있도록 해줍니다.

이러한 경우, 일반적으로 ResponseEntity에 감싸서 HTTP 응답을 반환해줍니다. 이 때, view를 반환할 때 사용했던 viewResolver 대신에 HttpMessageConverter가 동작합니다.

HttpMessageConverter는 여러 Converter가 등록되어 있으며, 반환해야 하는 데이터에 따라서 사용되는 Converter가 달라집니다. 단순 문자열의 경우, StringHttpMessageConverter가 사용되고, 객체의 경우에는 MappingJackson2HttpMessageConverter가 사용되며, 데이터 종류에 따라 서로 다른 mesageConverter가 작동하게 됩니다.

Spring은 클라이언트의 HTTP Accept 헤더와 서버의 컨트롤러 반환 타입 정보 둘을 조합하여 적합한 HttpMessageConverter를 선택하여 처리합니다. 이러한 MessageConverter의 동작은 HandlerAdapter와 Controller 간에서 요청을 주고 받는 시점에 수행됩니다.

@Controller
@RequiredArgsConstructor
public class ProductController {

	private final ProductService productService;

    @ResponseBody
    @GetMapping("/products")
    public ResponseEntity<Product> findUser(@RequestParam String name){
        return ResponseEntity.ok(productService.findProduct(name));
    }
    
    @GetMapping("/products/detailView")
    public String detailView(Model model, @RequestParam String name){
        Product product = productService.findProduct(name);
        model.addAttribute("product", product);
        return "/products/detailView";
    }
}

@RestController

@RestController는 @Controller에서 @ResponseBody가 추가된 어노테이션입니다. 주 사용은 Json 데이터를 HTTP 응답 바디에 담아 반환하는 것입니다.


@RestController
@RequiredArgsConstructor
public class ProductController {

	private final ProductService productService;

    @GetMapping("/products")
    public ResponseEntity<Product> findUser(@RequestParam String name){
        return ResponseEntity.ok(productService.findProduct(name));
    }
}

데이터를 반환할 때, 중요한 것은 클라이언트에게 HTTP 응답 상태 코드도 함께 전달해줘야 클라이언트도 요청에 대한 응답 처리가 어떻게 되었는지 알 수 있습니다. 따라서 ResponseEntity로 감싸서 응답 상태 코드도 함께 반환해줍니다.

결론

두 어노테이션의 차이는 Json 데이터를 반환해주느냐 View를 반환해주는 가의 차이입니다.

profile
백엔드 서버 엔지니어

0개의 댓글