Building Your First REST Controller
Build a real REST controller using @RestController and @GetMapping, returning both plain text and JSON responses.
Introduction
Everything covered so far — auto-configuration, starters, project structure, configuration files — exists to support one core goal: letting you write a handful of lines and get a working HTTP endpoint. This lesson puts it all together by building your first real REST controller.
@RestController
`@RestController` is a specialized version of `@Component` that tells Spring Boot "this class handles HTTP requests, and every method's return value should be written directly into the HTTP response body" (as opposed to being resolved as the name of a server-rendered view, which is what plain `@Controller` does).
Returning Plain Text
The simplest possible endpoint returns a plain `String`. The `@GetMapping` annotation maps HTTP GET requests at a given path to the annotated method.
package com.programinds.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;
@RestControllerpublic class GreetingController {
@GetMapping("/api/greeting") public String greeting() { return "Hello, PrograMinds learner!"; }}Click Run to see what this code prints.
Returning JSON
Real APIs almost always return structured data, not plain strings. Returning any plain Java object from a `@RestController` method causes Spring Boot to automatically serialize it into JSON using the Jackson library, which was already auto-configured for you when you added the web starter.
package com.programinds.demo.model;
public class Course {
private String title; private String level;
public Course(String title, String level) { this.title = title; this.level = level; }
public String getTitle() { return title; }
public String getLevel() { return level; }}package com.programinds.demo.controller;
import com.programinds.demo.model.Course;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;
@RestControllerpublic class CourseController {
@GetMapping("/api/course") public Course getCourse() { return new Course("Spring Boot", "Beginner to Advanced"); }}Click Run to see what this code prints.
No manual JSON conversion code was written anywhere. Spring Boot detected that Jackson was on the classpath, auto-configured a message converter for it, and used that converter to turn the returned `Course` object into a JSON response body automatically.
Testing the Endpoint
You can verify either endpoint using a browser, curl, or any HTTP client.
curl http://localhost:8080/api/courseClick Run to see what this code prints.
Common Mistakes
- Using plain @Controller when you actually want @RestController — @Controller expects methods to return a view name, not raw response data.
- Forgetting getter methods on a response object — Jackson relies on standard getters to serialize fields to JSON by default.
- Mapping two methods to the same path and HTTP method, which causes an ambiguous mapping error at startup.
Best Practices
- Keep controllers thin — delegate real business logic to a separate @Service class rather than writing it inline in the controller.
- Use dedicated response model classes (like Course above) instead of returning raw Maps for anything beyond the simplest prototype.
- Group related endpoints under a shared @RequestMapping base path on the controller class for consistency.
- Return meaningful HTTP status codes using ResponseEntity once your endpoints need more than a plain 200 OK.
Frequently Asked Questions
@Controller methods typically return a view name to be rendered as HTML. @RestController (which combines @Controller and @ResponseBody) writes the return value directly into the HTTP response body, usually serialized as JSON — ideal for REST APIs.
No. Once spring-boot-starter-web is on the classpath, Spring Boot auto-configures Jackson and its HTTP message converter automatically, so returning any plain object is serialized to JSON with zero extra setup.
Yes. A single controller class commonly contains multiple methods annotated with @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping for different endpoints and actions.
Key Takeaways
- @RestController combines @Controller and @ResponseBody, writing return values directly into the HTTP response.
- @GetMapping maps HTTP GET requests at a given path to a controller method.
- Returning a plain Java object is automatically serialized to JSON by the auto-configured Jackson converter.
- Controllers should stay thin, delegating real logic to services.
Summary
You have now built a working REST controller that returns both plain text and structured JSON, using nothing more than a couple of annotations and the auto-configuration you learned about earlier in this batch. Next, you will go deeper into request mapping annotations and learn how to handle path variables, query parameters, and different HTTP methods.