DTO는 로직을 갖고 있지 않는 순수한 데이터이며, Getter/Setter만을 갖는다.
DTO = Data Transfer Object
계층 간 데이터 교환
을 위한 객체(Java Beans)다.
@Controller
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@GetMapping("/members/new") //회원 가입
public String createForm(Model model) {
model.addAttribute("memberForm", new MemberForm());
return "members/createMemberForm";
}
}
@Getter @Setter
public class MemberForm {
@NotEmpty(message = "회원 이름은 필수입니다")
private String name;
private String city;
private String street;
private String zipcode;
}
위 코드의 memberForm과 같이 실제 엔티티가 아닌 오로지 전달을 목적으로 하는 객체를 말하며 DTO를 통해 구현한다.
참고: 요구사항이 정말 단순할 때는 폼 객체( MemberForm ) 없이 엔티티( Member )를 직접 등록과 수정 화면에서 사용해도 된다. 하지만 화면 요구사항이 복잡해지기 시작하면, 엔티티에 화면을 처리하기 위한 기능이 점점 증가한다. 결과적으로 엔티티는 점점 화면에 종속적으로 변하고, 이렇게 화면 기능 때문에 지저분해진 엔티티는 결국 유지보수하기 어려워진다.
실무에서 엔티티는 핵심 비즈니스 로직만 가지고 있고, 화면을 위한 로직은 없어야 한다. 화면이나 API에 맞는 폼 객체나 DTO를 사용하자.
그래서 화면이나 API 요구사항을 이것들로 처리하고, 엔티티는 최대한 순수하게 유지하자.
API별로 화면에 return하는 데이터가 달라 많은 DTO 파일을 생성할 수 있다.
만약 User 정보를 저장하는 api, 조회하는 api를 만드는 상황에서 필요한 DTO는
가 될 것이다. 이 세 DTO들을 하나의 클래스로 묶어 표현하면
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
public class User {
@Getter
@AllArgsConstructor
@Builder
public static class Info {
private int id;
private String name;
private int age;
}
@Getter
@Setter
public static class Request {
private String name;
private int age;
}
@Getter
@AllArgsConstructor
public static class Response {
private Info info;
private int returnCode;
private String returnMessage;
}
}
이와 같이 1개의 Class 파일로 깔끔하게 관리할 수 있게 된다.
import com.parksh.demo.dto.DefaultResponse;
import com.parksh.demo.dto.user.User;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(“user”)
public class UserController {
@GetMapping(“/{user_id}”)
public User.Response getUser(@PathVariable(“user_id”) String userId) {
return new User.Response(new User.Info(), 200, “success”);
}
@PostMapping
public DefaultResponse addUser(@RequestBody User.Info info) {
return new DefaultResponse();
}
}
참고
[DAO] DAO, DTO, Entity Class의 차이
DTO
Spring Boot에서 깔끔하게 DTO 관리하기