惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
有赞技术团队
有赞技术团队
L
LangChain Blog
C
Check Point Blog
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
美团技术团队
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News
WordPress大学
WordPress大学
aimingoo的专栏
aimingoo的专栏
S
SegmentFault 最新的问题
A
About on SuperTechFans
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
博客园 - 叶小钗
腾讯CDC
B
Blog
G
Google Developers Blog
The Cloudflare Blog
P
Proofpoint News Feed

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Spring Boot Controllers
Anthony Baño · 2026-05-11 · via DEV Community

Anthony Bañon Arias

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<T>.

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.


What Is a Controller?

A controller handles HTTP requests.

Its job is simple:

  1. Receive the request
  2. Call the service layer
  3. Return a response

Example:

@RestController
@RequestMapping("/api/users")
public class UserController {

}

Enter fullscreen mode Exit fullscreen mode


Most Common HTTP Annotations

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

1. Returning an Object Directly

Example

@GetMapping
public List<UserDTO> getAllUsers() {
    return userService.getAllUsers();
}

Enter fullscreen mode Exit fullscreen mode

What Spring Does Automatically

  • Converts the object to JSON
  • Returns 200 OK

Best For

  • Simple CRUD APIs
  • Clean code
  • Fast development

Advantages

Advantage Why
Less code No boilerplate
Easy to read Simple methods
Very common Standard REST pattern

2. Returning ResponseEntity<T>

Example

@GetMapping
public ResponseEntity<List<UserDTO>> getAllUsers() {
    return ResponseEntity.ok(userService.getAllUsers());
}

Enter fullscreen mode Exit fullscreen mode

Why Use It?

ResponseEntity gives full control over the HTTP response.

You can customize:

  • Status code
  • Headers
  • Body

Custom Example

return ResponseEntity
        .status(HttpStatus.CREATED)
        .body(user);

Enter fullscreen mode Exit fullscreen mode


Best For

  • Professional APIs
  • Authentication endpoints
  • Pagination
  • Custom status codes

Advantages

Advantage Why
Full HTTP control Status + headers
Flexible Many response options
Explicit Easy to understand behavior

3. Returning void

Example

@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteUser(@PathVariable Long id) {
    userService.delete(id);
}

Enter fullscreen mode Exit fullscreen mode

What Happens?

  • No response body
  • Returns HTTP 204 No Content

Best For

  • DELETE endpoints
  • Simple PATCH operations

Advantages

Advantage Why
Clean intent No unnecessary response
Lightweight Smaller HTTP response

4. Returning DTOs

Example

@PostMapping
public UserResponseDTO createUser(
        @RequestBody UserRequestDTO dto
) {
    return userService.create(dto);
}

Enter fullscreen mode Exit fullscreen mode


Why Use DTOs?

DTOs help separate:

  • API layer
  • Database entities

Benefits

Benefit Why
Security Avoid exposing internal fields
Clean architecture Better separation
Maintainability Easier future changes
API control Customize responses

5. Returning String

Example

@GetMapping("/ping")
public String ping() {
    return "OK";
}

Enter fullscreen mode Exit fullscreen mode

What It Returns

Plain text.

Best For

  • Health checks
  • Quick tests
  • Debugging

6. Returning HTML Views (ModelAndView)

Example

@GetMapping("/home")
public ModelAndView home() {
    return new ModelAndView("home");
}

Enter fullscreen mode Exit fullscreen mode


What Is This?

Traditional Spring MVC.

Instead of JSON, it returns an HTML page.

Usually used with:

  • Thymeleaf
  • JSP

Best For

  • Server-rendered applications
  • Traditional MVC projects

Important

Less common in modern REST APIs.

Most modern backends return JSON instead.


7. Asynchronous Controllers (CompletableFuture)

Example

@GetMapping
public CompletableFuture<List<UserDTO>> getUsers() {
    return userService.getAsyncUsers();
}

Enter fullscreen mode Exit fullscreen mode


What Happens?

The request is processed asynchronously.

The server thread is not blocked while waiting.


Best For

  • Slow external APIs
  • High traffic systems
  • Async operations

8. Reactive Controllers (Mono / Flux)

Example

@GetMapping
public Mono<UserDTO> getUser() {
    return userService.getUser();
}

Enter fullscreen mode Exit fullscreen mode


What Is This?

Reactive programming using Spring WebFlux.

Designed for non-blocking applications.


Reactive Types

Type Meaning
Mono<T> 0 or 1 result
Flux<T> Multiple results

Best For

  • Streaming
  • Real-time systems
  • Very high concurrency

Important

Requires Spring WebFlux.

Not the same as traditional Spring MVC.


Understanding Method Visibility

Sometimes you may see something like this:

private void processIncomingMessages(Map<String, Object> value)

Enter fullscreen mode Exit fullscreen mode

This is NOT an endpoint.


Why?

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.


Most Common Patterns in Real REST APIs

GET

@GetMapping
public List<UserDTO> getAll()

Enter fullscreen mode Exit fullscreen mode


POST

@PostMapping
public ResponseEntity<UserDTO> create()

Enter fullscreen mode Exit fullscreen mode


DELETE

@DeleteMapping("/{id}")
public void delete()

Enter fullscreen mode Exit fullscreen mode


Quick Cheat Sheet

Situation Recommended Return Type
Simple CRUD DTO/Object
Need status/header control ResponseEntity<T>
DELETE endpoint void
HTML pages ModelAndView
Async processing CompletableFuture
Reactive systems Mono / Flux

Final Thoughts

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.


References