@RestController
The most-used Spring Boot annotation — @Controller + @ResponseBody, Jackson serialization, HttpMessageConverter, return types, content negotiation and DTOs.
#Introduction
If you're a Java backend developer, this is probably the most frequently used annotation in Spring Boot — every REST API you build starts here. Understanding @RestController means understanding how Spring Boot converts your Java objects into JSON and sends them back to the client.
#What is @RestController?
@RestController is a specialized Spring annotation for creating RESTful web services. Unlike @Controller, it does not return a view (HTML/JSP/Thymeleaf). Instead, it returns data (usually JSON).
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "Rahul");
}
}GET /users/1 returns:
{
"id": 1,
"name": "Rahul"
}#Why Was @RestController Introduced?
Before Spring 4, developers wrote:
@Controller
public class UserController {
@ResponseBody
@GetMapping("/users")
public User getUser() {
return new User(1, "Rahul");
}
}Every REST method required @ResponseBody. Spring 4.0 simplified it — now we write @RestController public class UserController {}.
Internal Definition
Conceptually:
@Target(TYPE)
@Retention(RUNTIME)
@Controller
@ResponseBody
public @interface RestController {
}So every method automatically behaves as if it has @ResponseBody.
#@Controller vs @RestController
| Feature | @Controller | @RestController |
|---|---|---|
| Returns a view | ✓ | ✗ |
| Returns JSON | Only with @ResponseBody | ✓ |
| Used for | MVC applications | REST APIs |
| ViewResolver used | ✓ | ✗ |
| JSON conversion | Optional | Automatic |
Example
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home"; // Spring searches home.html or home.jsp
}
}@RestController
public class UserController {
@GetMapping("/")
public String home() {
return "Hello"; // the response body is literally: Hello
}
}No ViewResolver involved.
#Request Flow
For GET /users/10:
Spring receives a User; the browser receives JSON. Where did the JSON come from? Jackson.
#Jackson — Serialization and Deserialization
Spring Boot includes Jackson by default (via spring-boot-starter-web).
Jackson performs both automatically.
Complete REST Flow
Client sends POST /users with body {"name": "Rahul"}:
#@ResponseBody
@Controller
public class TestController {
@ResponseBody
@GetMapping("/hello")
public String hello() {
return "Hello";
}
}- Without
@ResponseBody, Spring thinksHellois a view name. - With
@ResponseBody, Spring writesHellodirectly into the HTTP response body.
@RestController applies this behaviour to all methods.
#HttpMessageConverter
Interviewers love this topic. The controller returns a User — who converts it into JSON? An HttpMessageConverter.
This converter is automatically registered by Spring Boot.
#Returning Different Types
| Return type | Response |
|---|---|
User | JSON object { ... } |
List<User> | JSON array [ {}, {}, {} ] |
Map<String, Object> | JSON object, e.g. {"name": "Rahul", "age": 25} |
String | Plain text, e.g. Hello |
ResponseEntity<User> | Full control over status, headers and body |
Professional APIs usually return ResponseEntity:
@GetMapping("/{id}")
public ResponseEntity<User> get(@PathVariable Long id) {
return ResponseEntity.ok(user);
// or: return ResponseEntity.notFound().build();
}This gives complete control over status code, headers and body. (ResponseEntity has its own chapter.)
#Content Negotiation
If the client sends Accept: application/json, Spring returns JSON. If it sends Accept: application/xml and XML converters are configured (e.g. jackson-dataformat-xml), Spring can return XML instead. This is called content negotiation.
#REST APIs Are Stateless
Controllers should not store user-specific data — multiple users share the same controller instance.
// ❌ Wrong
@RestController
public class UserController {
private User currentUser;
}
// ✅ Correct — use method parameters and local variables
@GetMapping("/{id}")
public User get(@PathVariable Long id) {
}#Common Mistakes
Returning Entities Directly
Large projects usually return DTOs instead:
Business Logic in the Controller
@RestController
public class UserController {
@PostMapping
public void save() {
calculateSalary(); // ❌
calculateTax(); // ❌
repository.save(); // ❌
}
}Correct: Controller → Service → Repository.
Returning Sensitive Fields
class User {
private String password;
}Returning this directly could expose passwords. Use DTOs, or annotations such as @JsonIgnore where appropriate.
#Real Enterprise Architecture
#Internal Working
#Interview Questions
Q1What is @RestController?
A stereotype annotation used to build REST APIs. It combines @Controller and @ResponseBody, so return values are written directly to the HTTP response body.
Q2What is the difference between @Controller and @RestController?
@Controller is typically used for MVC applications that return views, while @RestController is used for REST APIs that return data such as JSON or XML.
Q3What is @ResponseBody?
It tells Spring to write the return value directly into the HTTP response body instead of resolving it as a view.
Q4Who converts Java objects into JSON?
Spring delegates to an HttpMessageConverter — typically the Jackson converter (MappingJackson2HttpMessageConverter), which uses the Jackson library to serialize Java objects into JSON.
Q5What is serialization?
Converting a Java object into JSON.
Q6What is deserialization?
Converting JSON into a Java object.
Q7What is content negotiation?
Spring examines the client's Accept header and selects an appropriate HttpMessageConverter (for example JSON or XML) to generate the response.
Q8Why should controllers return DTOs instead of entities?
DTOs hide sensitive fields, decouple API contracts from persistence models, and avoid issues such as lazy-loading exceptions.
#Key Takeaways
@RestController=@Controller+@ResponseBody.- It's designed for REST APIs that return data instead of views.
DispatcherServletroutes requests.HttpMessageConverterand Jackson handle JSON serialization and deserialization.- REST controllers should remain stateless and delegate business logic to services.
- Returning DTOs is generally preferable to returning JPA entities directly.