Spring Boot Controllers

Published: (May 10, 2026 at 06:01 PM EDT)
4 min read
Source: Dev.to

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

0 views
Back to Blog

Related posts

Read more »