[Spring Boot] @Controller과 @RestController의 차이

k·2024년 2월 6일

spring boot

목록 보기
2/4

Spring Boot 을 배우면서, 초기에 Controller를 선언하고 Restful한 응답을 하려고 했지만 예상처럼 응답이 되지않았다.

이는 Controller의 본래의 목적을 정확히 이해하지 못했기 때문에 일어난 일이다.

바로 위에, Spring MVC 원리에 대한 그림이 있다.

이 그림만 보면 View Resolver를 통한 View 반환이 필수적이라고 생각이 된다. 하지만, ViewResolver를 거치지않고 HTTP 응답을 진행 할 수도 있다는 것을 알고있어야한다.

아래는 이와 같이 View가 아닌 HTTP를 통해서 응답데이터를 보내고 싶을 때, 어떻게 해야하는지에 대한 설명이 간단하게 나와있다.

" 그래서 @Controller 가 뭔데? "

@Controller는 일반적으로 다음과 같은 역할을 수행한다.

  1. 클라이언트로부터의 요청을 받는다.
  2. 해당 요청에 대응하는 비즈니스 로직을 수행한다.
  3. View의 이름을 반환한다.

이는 View Resolver에 의해 실제 View로 해석되어 클라이언트에 반환됩니다.

만약에, @ResponseBody 라는 어노테이션이 추가 되면, Http 응답을 즉시 수행한다. ResponseBody 내에는 반환 값이 들어간다.

이는 View Resolver까지 거치지않는다는 것을 의미한다.

일단 여기서 잠깐 정리를 하고 가자면, View 는 보통 SSR(Server Side Rendering) 방식을 위해 주로 운용된다.

하지만 Restful api 를 만들게 된다 생각해보자. View 보다는 해당 요청에 맞는 응답 데이터를 http 응답으로 즉시 반환하도록 해야한다.

이를 @ResponseBody를 통해 도움을 받을 수 있지만, @ResponseBody는 클래스 레벨을 지정하지는 못하고, 메소드 레벨에서 사용 가능하기 때문에, Restful api 구조로 개발을 하기위해서는 메소드 위에 @ResponseBody를 적어야한다.

이는 굉장히 비효율적인 작업이다.
이를 막기 위해서 Restful Api구조 개발을 보다 편리하게 진행 할 수 있게 @Controller + @ResponseBody 가 기본으로 지원 되는 어노테이션을 Spring내에서 지원한다.

"그럼 @RestController 는 뭐야?"

위에서도 말했지만, @Controller 와 ResponseBody 가 합쳐진 구조이다.
@RestController는 클래스내에 Mapping 된 모든 메소드를 ResponseBody가 적용되게 된다. 그래서 모든 메소드는 View Resolver를 거치치않고, Http 본문으로 응답으로 가능 하게 해준다.

실제 사용 예시

@Controller를 통한 view의 이름 반환

@Controller
@RequestMapping("/api")
class TestController{
	@GetMapping("/")
    public String test(){
		return "test";
	}
}

test라는 이름의 View를 view resolver가 찾아서, 실제 view를 반환하게 된다.

@Controller를 통한 HTTP 응답

@Controller
@RequestMapping("/api")
class TestController{
	@GetMapping("/")
    @ResponseBody
    public String test(){
		return "test";
	}
}

test라는 문자열이 HTTP 응답 본문으로 반환

@RestController를 통한 클래스 레벨의 HTTP 응답

@RestController
@RequestMapping("/api")
class TestController{
	@GetMapping("/t1")
    public String test(){
		return "test";
	}
	@GetMapping("/t2")
    public String test2(){
		return "test2";
	}
	@GetMapping("/t3")
    public String test3(){
		return "test3";
	}
}

@ResponseBody 를 적지않았지만, 본문에 아래와 같은 응답 데이터가 담긴다.

UrlMethodResponse
/api/t1GETtest
/api/t2GETtest2
/api/t3GETtest3

위와 같이 Restful하게 응답을 받을 수 있다.텍스트

profile
You must do the things you think you cannot do

0개의 댓글