Data Transfer Object라는 의미를 가지고 계층 간의 데이터 교환을 위해서만 사용하는 객체를 의미한다. MVC 패턴의 경우 Controller가 Model을 통해 수행한 비즈니스 로직에 대한 결과를 도메인에 담아서 View에 전달하는 것이 아닌 각 view에서 필요한 도메인 정보의 일부만으로 구성된 개별 DTO를 사용해 전달하게 되면 비즈니스 레이어와 프레젠테이션 레이어 사이에 의존성을 낮추고 독립적인 개발이 가능하게 하는 역할을 수행한다.
비즈니스 레이어에서 나온 결과를 view에 반환하기 위해 사용하는 경우에서 DTO를 사용하게 되고 절차는 다음과 같다.
각 도메인에서 view에서 필요한 부분만을 추출한 DTO를 구성한다.
@Getter
@Setter
public class User {
private String id;
private String name;
private String password;
private int age;
public User(String name, String password, int age) {
this.name = Objects.requireNonNull(name);
this.password = this.encrypt(password);
this.age = age;
}
String encrypt(String password) {
// encryption logic
}
}
@Getter
@AllArgsConsturctor
public class UserDTO {
private String name;
private int age;
}
도메인과 DTO 사이를 서로 변환시켜줄 Mapper를 구현한다.
@Component
class Mapper {
public UserDTO toDto(User user) {
String name = user.getName();
int age = user.getAge();
return new UserDTO(name, age);
}
public User toUser(UserDto userDto) {
return new User(userDto.getName(), userDto.getAge());
}
}
Controller에서 서비스 로직에 대한 결과를 mapper를 사용해서 변환시킨 후 View에서 사용할 Model로 저장해준다.
@RestController
@RequestMapping("/users")
class UserController {
private UserService userService;
private Mapper mapper;
@GetMapping
@ResponseBody
public List<UserDTO> getUsers() {
return userService.getAll()
.stream()
.map(mapper::toDto)
.collect(toList());
}
@PostMapping
@ResponseBody
public UserDto createUser(@RequestBody UserDto userDto) {
User user = mapper.toUser(userDto);
return userDto;
}
}