어느날 Spring 서버 개발중 Controller를 만들 때, 자연스럽게 클래스위에 @RestController를 붙이고 있었다. 단순 REST API의 Controller 담당한다는 의미로만 생각했고, 의미를 정확하게 파악하지 못한채 사용하고 있었다. 그래서 RestController에 대해서 한번 알아보려 한다.
Controller를 의미하는 어노테이션은 총 2가지가 있다고 한다. 하나는 @Controller, 다른 하나는 @RestController이다. 두개의 차이점을 분석하기 위해 어노테이션을 직접 확인해 봤다.
아래는 @Controller 인터페이스이다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* Alias for {@link Component#value}.
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
아래는 @RestController 인터페이스이다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(annotation = Controller.class)
String value() default "";
}
자세히 보면 @RestController는 @Controller를 이미 포함하고 있다. 그런데 추가로 @ResponseBody가 있다. 즉 @RestController와 @Controller의 차이는 @ResponseBody 유무의 차이인 것이다. 그래서 @ResponseBody에 대해서도 확인을 해보았다.
아래는 @ResponseBody 인터페이스이다.
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
@ResponseBody 인터페이스에 상위에 주석이 작성되어있는데, 아래와 같다.
Annotation that indicates a method return value should be bound to the web response body. Supported for annotated handler methods.
As of version 4.0 this annotation can also be added on the type level in which case it is inherited and does not need to be added on the method level.
즉, @ResponseBody 어노테이션을 붙이면 속한 메소드의 반환값을 http 응답 body에 넣어준다는 의미이다.
@Controller와 @RestController의 차이는 response data의 목적이라고 할 수 있다. @Controller는 Spring MVC에서 주로 View를 반환을 하는 데 목적이 있고, @RestController는 JSON 데이터 타입을 주로 반환하는데 목적이 있다. 추가로 @Controller에는 View Resolver가 동작하여 반환된 문자열을 기반으로 해당하는 뷰를 찾고, 그 뷰를 사용자에게 렌더링 한다고 한다. 즉, 나는 프론트, 백엔드가 나뉘어져 백엔드 데이터만 전달하는 역할을 해왔기 때문에 @RestController를 자연스럽게 사용을 했던 것 같다.
Spring MVC와 같이 View를 반환해야 한다면 @Controller를 사용하고, 데이터 전달이 목적이라면 @RestController를 사용하면 된다.