hayu's 개발 일지

[TIL]240501 DTO 본문

프레임워크/spring

[TIL]240501 DTO

hayu00 2024. 5. 1. 21:23

DTO

  • DTO(Data Transfer Object)는 데이터 전송 객체를 의미한다. 계층 간 데이터 전송을 위해 도메인 모델 대신 사용되는 객체다.
  • 데이터를 전송하기 위해 사용하는 객체이기 때문에 순수하게 전달하고 싶은 데이터만 담겨있다.

dto를 사용하지 않고, 엔티티로 사용하면?

  • 엔티티의 모든 속성이 외부에 노출된다. 예를 들어, UserEntity를 사용하면 민감한 정보가 외부에 노출될 수 있다.
  • Model과 View가 강하게 결합되어, View의 요구사항 변화가 Model에 영향을 끼치기 쉽습니다.
    • 또한 UserEntity의 속성이 변경되면, View가 전달받을 JSON 및 프론트엔드 Js 코드에도 변경을 유발하기 때문에 상호간 강하게 결합됩니다.

dto를 사용하면

⇒ Model을 캡슐화하고, 프론트에서 원하는 데이터만 선택적으로 보낼 수 있다.

 

코드예시

엔티티코드

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
@Table(name = "member_tbl")
public class Member extends Timestamped {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;

    @Column(unique = true, nullable = false)
    private String nickname;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private RoleType role;

    @Builder
    public Member(String email, String password, String nickname, RoleType role) {
        this.email = email;
        this.password = password;
        this.nickname = nickname;
        this.role = role;
    }
}

dto코드(중첩 클래스 사용)

public class MemberRequestDto {

    @Getter
    public static class SignupMemberRequestDto {

        @NotBlank(message = "이메일을 입력해주세요.")
        @Email(message = "이메일 형식에 맞춰주세요.")
        private String email;

        @NotBlank(message = "비밀번호를 입력해주세요.")
        @Pattern(
                regexp = "^(?=.*[a-zA-Z])(?=.*\\\\d).{8,}$",
                message = "영문, 숫자를 포함한 8자 이상의 비밀번호를 입력하세요."
        )
        private String password;

        @NotBlank(message = "비밀번호 확인을 입력해주세요.")
        private String passwordCheck;

        @NotBlank(message = "닉네임을 입력해주세요.")
        private String nickname;

        public Member toEntity(String encodedPassword) {
            return Member.builder()
                    .email(this.email)
                    .password(encodedPassword)
                    .nickname(this.nickname)
                    .role(RoleType.ROLE_USER)
                    .build();
        }
    }

    @Getter
    public static class SigninMemberRequestDto {

        @NotBlank(message = "이메일을 입력해주세요.")
        private String username;

        @NotBlank(message = "비밀번호를 입력해주세요.")
        private String password;
    }
}

public class MemberResponseDto {

    @Getter
    public static class SignupMemberResponseDto {

        private final String email;
        private final String nickname;

        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
        private final LocalDateTime createdAt;

        public SignupMemberResponseDto(Member member) {
            this.email = member.getEmail();
            this.nickname = member.getNickname();
            this.createdAt = member.getCreatedAt();
        }
    }

    @Getter
    public static class SigninMemberResponseDto {

        private final String email;

        public SigninMemberResponseDto(Member member) {
            this.email = member.getEmail();
        }
    }

    @Getter
    public static class CheckMemberResponseDto {

        private final Boolean isExist;

        public CheckMemberResponseDto(Boolean isExist) {
            this.isExist = isExist;
        }
    }
}