A common interview question is: why does Java have so many objects ending in “O” — PO, DTO, VO, BO, and so on?

What usually makes this question tricky is not memorizing the names, but understanding how they connect in a real request flow. A clearer way to think about it is to place them inside an actual business scenario instead of treating them as isolated definitions.

Here, the example is a user query API built with Spring Boot + MyBatis. The goal is simple: the frontend calls GET /user?userId=123, and the backend returns the user’s name plus the number of days since registration.

A concrete scenario: querying user information

Requirement: the frontend requests GET /user?userId=123 to fetch user data.

Expected response: the backend returns the user’s name and registered days.

Tech stack: Spring Boot + MyBatis.

This kind of example is useful because the different “O” types are easier to understand when they appear along an actual request chain.

Looking at the request flow

Controller layer: use a DTO for input

public class UserQueryDTO {
    private Long userId;
    private Integer page;
    private Integer size;
    // getters and setters
}

@RestController
public class UserController {
    private final UserService userService;

    @GetMapping("/user")
    public UserVO getUser(@RequestParam UserQueryDTO queryDTO) {
        return userService.getUserInfo(queryDTO);
    }
}

In this step, the incoming parameter object is a DTO.

What DTO means here

DTO stands for Data Transfer Object. Its place in the system is straightforward: it is used to carry input data coming from the frontend.

Instead of scattering parameters directly across a controller method signature, the request data is wrapped into a structured object such as UserQueryDTO.

Why DTO is useful

Its value in this scenario is mainly reflected in two points:

  • It organizes request parameters into a clear structure, which also makes it easier to combine with validation mechanisms such as @Valid.
  • It avoids piling multiple parameters into the method signature, improving readability and making the controller interface easier to maintain.

So when people talk about all those Java “O” objects, the important part is not the suffix itself. What matters is the responsibility each object takes in a specific layer. In this example, the DTO’s job is simply to receive and carry request data cleanly at the controller boundary.