The Big Confusion in Spring Boot
When developers start writing web backends in Spring Boot, they often encounter both annotations:@Controller and@RestController. Many assume they simply do the same thing.
“Many beginners think both are the same. But they are used for completely different purposes. Understanding this distinction is foundational for clean backend engineering and acing Spring interviews.”
The difference comes down to what the HTTP client expects back: a rendered web page (HTML), or raw data (JSON/XML).
Every method in a @RestController implicitly inherits @ResponseBody behavior.
What is @Controller?
@Controller is the traditional Spring MVC annotation introduced in Spring 2.5. Its primary responsibility is to return views (HTML web pages).
It works directly with template engines:
- Thymeleaf: Modern server-side Java template engine
- JSP (JavaServer Pages): Legacy Java EE view technology
- Freemarker / Mustache / Groovy: Server template formats
// Traditional Spring MVC Controller
// Returns View Name resolved by ViewResolver (e.g. Thymeleaf, JSP)
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("username", "Shyam");
// Spring looks for templates/home.html or home.jsp
return "home";
}
}"home" is passed to the configured ViewResolver. It looks for a template file (such as src/main/resources/templates/home.html) and renders it with the model attributes.What is @RestController?
@RestController was introduced in Spring 4.0 specifically for building RESTful Web Services. It tells Spring that every handler method inside this class will return data directly (not an HTML page).
What @RestController returns:
- JSON: Default serialization using Jackson (
application/json) - XML: When Jackson XML or JAXB is present on classpath
- API Responses: Directly written into the HTTP response body
// Modern REST API Controller
// Returns raw data (JSON/XML) directly to the client
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/user")
public UserResponse getUser() {
// Automatically serialized into JSON via Jackson ObjectMapper
return new UserResponse(101L, "Shyam Kumar", "shyam@example.com");
}
}Notice that when getUser() returns "Shyam" or an object, Spring does NOT look for a template called "Shyam.html". Instead, it writes the payload directly into the HTTP response.
Key Differences at a Glance
Here is the clear architectural comparison:
| Criteria | @Controller | @RestController |
|---|---|---|
| Primary Output | Returns View (HTML / JSP / Thymeleaf) | Returns Data (JSON / XML) |
| Application Type | Used in traditional MVC web apps | Used in REST APIs & Microservices |
| @ResponseBody Need | Must add @ResponseBody manually to return data | Already includes it automatically |
| ViewResolver | Active (Resolves template path) | Bypassed (HttpMessageConverter writes response) |
| Client Consumer | Web Browsers rendering full HTML | Mobile Apps, React, Angular, Next.js, 3rd party APIs |
The Practical Rule of Thumb
Building server-side rendered pages → Use @Controller
If you are serving traditional HTML pages using Thymeleaf, JSP, or Freemarker where the backend renders the complete page markup.
Building RESTful services → Use @RestController
If you are building APIs consumed by a frontend Single Page App (React, Vue, Next.js), mobile applications (iOS, Android), or microservices.
@Controller without @ResponseBody?Answer: Spring's
DispatcherServlet will interpret that string as a view name and ask the ViewResolver to locate an HTML/JSP file with that name. If the template file doesn't exist, it throws a 404 Not Found or Circular view path error.Simple Rule. Clear Understanding. Better Interviews.
Remembering that @RestController = @Controller + @ResponseBody eliminates 90% of beginner errors in Spring Boot. Choose the right tool based on whether your consumers require HTML pages or JSON data.
Did you find this breakdown helpful?
Please like and share it with your friends and fellow backend engineers!