Spring Boot Controllers
Source: Dev.to
⚠️ Collection Error: Content refinement error: Error: 429 “you (bkperio) have reached your weekly usage limit, upgrade for higher limits: https://ollama.com/upgrade (ref: 640bc8ab-68c5-4536-acd4-6507bb2e07e3)”
When learning Spring Boot, one of the most confusing things is seeing controllers written in many different ways. Sometimes a method returns a DTO. Sometimes ResponseEntity. Sometimes void, String, ModelAndView, CompletableFuture, Mono, and more. At first it feels random. But each return type has a specific purpose. This article is a practical cheat sheet to quickly understand the most common controller patterns in Spring Boot REST APIs. A controller handles HTTP requests. Its job is simple: Receive the request Call the service layer Return a response Example: @RestController @RequestMapping(“/api/users”) public class UserController {
}
Annotation HTTP Method Purpose
@GetMapping GET Retrieve data
@PostMapping POST Create data
@PutMapping PUT Replace/update completely
@PatchMapping PATCH Partial update
@DeleteMapping DELETE Delete data
@GetMapping public List getAllUsers() { return userService.getAllUsers(); }
Converts the object to JSON Returns 200 OK
Best For
Simple CRUD APIs Clean code Fast development
Advantage Why
Less code No boilerplate
Easy to read Simple methods
Very common Standard REST pattern
ResponseEntity
Example
@GetMapping public ResponseEntity> getAllUsers() { return ResponseEntity.ok(userService.getAllUsers()); }
ResponseEntity gives full control over the HTTP response. You can customize: Status code Headers Body return ResponseEntity .status(HttpStatus.CREATED) .body(user);
Professional APIs Authentication endpoints Pagination Custom status codes
Advantage Why
Full HTTP control Status + headers
Flexible Many response options
Explicit Easy to understand behavior
void
Example
@DeleteMapping(”/{id}”) @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteUser(@PathVariable Long id) { userService.delete(id); }
No response body Returns HTTP 204 No Content
Best For
DELETE endpoints Simple PATCH operations
Advantage Why
Clean intent No unnecessary response
Lightweight Smaller HTTP response
@PostMapping public UserResponseDTO createUser( @RequestBody UserRequestDTO dto ) { return userService.create(dto); }
DTOs help separate: API layer Database entities
Benefit Why
Security Avoid exposing internal fields
Clean architecture Better separation
Maintainability Easier future changes
API control Customize responses
String
Example
@GetMapping(“/ping”) public String ping() { return “OK”; }
Plain text. Health checks Quick tests Debugging ModelAndView)
Example
@GetMapping(“/home”) public ModelAndView home() { return new ModelAndView(“home”); }
Traditional Spring MVC. Instead of JSON, it returns an HTML page. Usually used with: Thymeleaf JSP Server-rendered applications Traditional MVC projects Less common in modern REST APIs. Most modern backends return JSON instead. CompletableFuture)
Example
@GetMapping public CompletableFuture> getUsers() { return userService.getAsyncUsers(); }
The request is processed asynchronously. The server thread is not blocked while waiting. Slow external APIs High traffic systems Async operations Mono / Flux)
Example
@GetMapping public Mono getUser() { return userService.getUser(); }
Reactive programming using Spring WebFlux. Designed for non-blocking applications.
Type Meaning
Mono 0 or 1 result
Flux Multiple results
Streaming Real-time systems Very high concurrency Requires Spring WebFlux. Not the same as traditional Spring MVC. Sometimes you may see something like this: private void processIncomingMessages(Map value)
This is NOT an endpoint. Because:
Keyword Meaning
private Internal method only
void Returns nothing
And it has no: @GetMapping @PostMapping @PutMapping etc. Usually these are helper methods used internally by the controller. @GetMapping public List getAll()
@PostMapping public ResponseEntity create()
@DeleteMapping(”/{id}”) public void delete()
Situation Recommended Return Type
Simple CRUD DTO/Object
Need status/header control ResponseEntity
DELETE endpoint void
HTML pages ModelAndView
Async processing CompletableFuture
Reactive systems
Mono / Flux
One of the strange things about learning Spring Boot is realizing there are multiple valid ways to build controllers. At first that feels confusing. Later, it becomes flexibility. In real-world REST APIs, the most common patterns are: DTOs ResponseEntity void for DELETE operations The rest are specialized tools for specific situations. Once you understand why each one exists, Spring controllers become much easier to read and design. Spring Framework Documentation Oracle Java Documentation Baeldung – Spring REST Controllers Devdocs