DTO 클래스에 Swagger 어노테이션 추가

뚜우웅이·2025년 4월 21일

캡스톤 디자인

목록 보기
15/35

UserDto

public class UserDto {

    @Schema(description = "프로필 업데이트 요청")
    public record ProfileUpdateRequest(
            @Schema(description = "사용자 이름", example = "홍길동")
            @NotBlank(message = "이름은 필수 입력값입니다.")
            String name,

            @Schema(description = "휴대폰 번호", example = "010-1234-5678")
            @Pattern(regexp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$", message = "휴대폰 번호 형식이 올바르지 않습니다.")
            String phone
    ) {
    }

    @Schema(description = "비밀번호 변경 요청")
    public record PasswordChangeRequest(
            @Schema(description = "현재 비밀번호", example = "currentPass123")
            @NotBlank(message = "현재 비밀번호는 필수 입력값입니다.")
            String currentPassword,

            @Schema(description = "새 비밀번호", example = "newPass456")
            @NotBlank(message = "새 비밀번호는 필수 입력값입니다.")
            @Size(min = 8, message = "비밀번호는 최소 8자 이상이어야 합니다.")
            String newPassword
    ) {
    }

    @Builder
    @Schema(description = "사용자 응답 정보")
    public record UserResponse(
            @Schema(description = "사용자 ID", example = "1")
            Long id,

            @Schema(description = "이메일", example = "user@example.com")
            String email,

            @Schema(description = "이름", example = "홍길동")
            String name,

            @Schema(description = "휴대폰 번호", example = "010-1234-5678")
            String phone,

            @Schema(description = "사용자 역할", example = "일반 사용자")
            String role
    ) {
        public static UserResponse from(User user) {
            return UserResponse.builder()
                    .id(user.getId())
                    .email(user.getEmail())
                    .name(user.getName())
                    .phone(user.getPhone())
                    .role(user.getRole().getDisplayName())
                    .build();
        }
    }
}

ProductDto

public class ProductDto {

    @Schema(description = "상품 생성 요청")
    public record CreateRequest(
            @Schema(description = "상품명", example = "새 노트북")
            @NotBlank(message = "상품명은 필수 입력값입니다.")
            String name,

            @Schema(description = "상품 설명", example = "거의 사용하지 않은 노트북입니다.")
            String description,

            @Schema(description = "가격", example = "1000000")
            @NotNull(message = "가격은 필수 입력값입니다.")
            @Min(value = 0)
            Long price,

            @Schema(description = "재고 수량", example = "1")
            @NotNull(message = "재고는 필수 입력값입니다.")
            @Min(value = 1, message = "재고는 최소 1개 이상이어야 합니다.")
            Integer stock,

            @Schema(description = "상품 카테고리", example = "ELECTRONICS")
            @NotNull(message = "카테고리는 필수 입력값입니다.")
            ProductCategory category
    ) {}

    @Schema(description = "상품 수정 요청")
    public record UpdateRequest(
            @Schema(description = "상품명", example = "새 노트북")
            @NotBlank(message = "상품명은 필수 입력값입니다.")
            String name,

            @Schema(description = "상품 설명", example = "거의 사용하지 않은 노트북입니다.")
            String description,

            @Schema(description = "가격", example = "900000")
            @NotNull(message = "가격은 필수 입력값입니다.")
            @Min(value = 100, message = "가격은 최소 100원 이상이어야 합니다.")
            Long price,

            @Schema(description = "재고 수량", example = "1")
            @NotNull(message = "재고는 필수 입력값입니다.")
            @Min(value = 1, message = "재고는 최소 1개 이상이어야 합니다.")
            Integer stock,

            @Schema(description = "상품 카테고리", example = "ELECTRONICS")
            @NotNull(message = "카테고리는 필수 입력값입니다.")
            ProductCategory category,

            @Schema(description = "상품 상태", example = "ACTIVE")
            ProductStatus status
    ){}

    @Builder
    @Schema(description = "상품 응답")
    public record ProductResponse(
            @Schema(description = "상품 ID", example = "1")
            Long id,
            
            @Schema(description = "상품명", example = "새 노트북")
            String name,
            
            @Schema(description = "상품 설명", example = "거의 사용하지 않은 노트북입니다.")
            String description,
            
            @Schema(description = "가격", example = "1000000")
            Long price,
            
            @Schema(description = "재고 수량", example = "1")
            Integer stock,
            
            @Schema(description = "카테고리 표시명", example = "전자기기")
            String category,
            
            @Schema(description = "상품 상태", example = "판매중")
            String status,
            
            @Schema(description = "썸네일 이미지 URL", example = "https://example.com/thumbnail.jpg")
            String thumbnailUrl,
            
            @Schema(description = "이미지 URL 목록")
            List<String> imageUrls,
            
            @Schema(description = "판매자 ID", example = "123")
            Long sellerId,
            
            @Schema(description = "판매자 이름", example = "홍길동")
            String sellerName
    ) {
        public static ProductResponse from(Product product) {
            return ProductResponse.builder()
                    .id(product.getId())
                    .name(product.getName())
                    .description(product.getDescription())
                    .price(product.getPrice())
                    .stock(product.getStock())
                    .category(product.getCategory().getDisplayName())
                    .status(product.getStatus().getDisplayName())
                    .thumbnailUrl(product.getRepresentativeThumbnailUrl())
                    .imageUrls(product.getImages().stream()
                            .map(ProductImage::getImageUrl)
                            .collect(Collectors.toList()))
                    .sellerId(product.getSeller().getId())
                    .sellerName(product.getSeller().getName())
                    .build();
        }
    }
}

UserProfileDto

public class UserProfileDto {

    @Builder
    @Schema(description = "판매 상품 내역")
    public record SellingProductResponse(
            @Schema(description = "상품 ID", example = "1")
            Long productId,
            
            @Schema(description = "상품명", example = "새 노트북")
            String name,
            
            @Schema(description = "가격", example = "1000000")
            Long price,
            
            @Schema(description = "카테고리", example = "전자기기")
            String category,
            
            @Schema(description = "상품 상태", example = "판매중")
            String status,
            
            @Schema(description = "썸네일 URL", example = "https://example.com/thumbnail.jpg")
            String thumbnailUrl,
            
            @Schema(description = "구매자 이름", example = "김철수")
            String buyerName,
            
            @Schema(description = "판매 완료 날짜", example = "2025-04-21T12:00:00")
            LocalDateTime soldDate,
            
            @Schema(description = "상품 등록 날짜", example = "2025-04-20T10:00:00")
            LocalDateTime createdDate
    ) {}

    @Builder
    @Schema(description = "판매 내역 페이지 응답")
    public record SellingHistoryResponse(
        @Schema(description = "판매 중인 상품 목록")
        List<SellingProductResponse> activeProducts,
        
        @Schema(description = "판매 완료된 상품 목록")
        List<SellingProductResponse> soldProducts,
        
        @Schema(description = "총 상품 수", example = "10")
        int totalProductCount
    ) {}

    @Builder
    @Schema(description = "구매 내역 항목")
    public record PurchaseItem(
        @Schema(description = "상품 ID", example = "1")
        Long productId,
        
        @Schema(description = "상품명", example = "중고 책")
        String productName,
        
        @Schema(description = "구매 가격", example = "15000")
        Long price,
        
        @Schema(description = "카테고리", example = "도서")
        String category,
        
        @Schema(description = "썸네일 URL", example = "https://example.com/thumbnail.jpg")
        String thumbnailUrl,
        
        @Schema(description = "판매자 이름", example = "이영희")
        String sellerName,
        
        @Schema(description = "구매 날짜", example = "2025-04-20T14:30:00")
        LocalDateTime purchaseDate
    ) {}

    @Builder
    @Schema(description = "구매 내역 페이지 응답")
    public record PurchaseHistoryResponse(
            @Schema(description = "구매 내역 목록")
            List<PurchaseItem> purchases,
            
            @Schema(description = "총 구매 수", example = "5")
            int totalPurchaseCount
    ) {}

    @Builder
    @Schema(description = "프로필 요약 정보")
    public record ProfileSummaryResponse(
            @Schema(description = "사용자 ID", example = "1")
            Long userId,
            
            @Schema(description = "이메일", example = "user@example.com")
            String email,
            
            @Schema(description = "이름", example = "홍길동")
            String name,
            
            @Schema(description = "총 판매 중인 상품 수", example = "3")
            int totalSellingCount,
            
            @Schema(description = "총 판매 완료 수", example = "7")
            int totalSoldCount,
            
            @Schema(description = "총 구매 수", example = "15")
            int totalPurchaseCount,
            
            @Schema(description = "평균 평점", example = "4.5")
            double averageRating,
            
            @Schema(description = "가입 날짜", example = "2025-01-01T09:00:00")
            LocalDateTime joinDate
    ) {}
}

ResponseDto

@Getter
@Builder
@Schema(description = "통합 응답 DTO")
public class ResponseDTO<T> {
    @Schema(description = "요청 성공 여부", example = "true")
    private final boolean success;
    
    @Schema(description = "HTTP 상태 코드", example = "200")
    private final int status;
    
    @Schema(description = "응답 메시지", example = "요청이 성공했습니다.")
    private final String message;
    
    @Schema(description = "응답 데이터")
    private final T data;
    
    @Schema(description = "응답 시간", example = "2025-04-21T12:00:00")
    private final LocalDateTime timestamp;

    public static <T> ResponseDTO<T> success(T data) {
        return ResponseDTO.<T>builder()
                .success(true)
                .status(200)
                .message("요청이 성공했습니다.")
                .data(data)
                .timestamp(LocalDateTime.now())
                .build();
    }
    
    public static <T> ResponseDTO<T> success(T data, String message) {
        return ResponseDTO.<T>builder()
                .success(true)
                .status(200)
                .message(message)
                .data(data)
                .timestamp(LocalDateTime.now())
                .build();
    }

    public static <T> ResponseDTO<T> error(int status, String message) {
        return ResponseDTO.<T>builder()
                .success(false)
                .status(status)
                .message(message)
                .timestamp(LocalDateTime.now())
                .build();
    }

    public static <T> ResponseDTO<T> error(int status, String message, T data) {
        return ResponseDTO.<T>builder()
                .success(false)
                .status(status)
                .message(message)
                .data(data)
                .timestamp(LocalDateTime.now())
                .build();
    }
}

AuthDto

public class AuthDto {

    @Schema(description = "회원가입 요청")
    public record SignupRequest(
            @Schema(description = "이메일 주소", example = "user@example.com")
            @NotBlank(message = "이메일은 필수 입력값입니다.")
            @Email(message = "이메일 형식이 올바르지 않습니다.")
            String email,

            @Schema(description = "비밀번호 (최소 8자 이상)", example = "password123")
            @NotBlank(message = "비밀번호는 필수 입력값입니다.")
            @Size(min = 8, message = "비밀번호는 최소 8자 이상이어야 합니다.")
            String password,

            @Schema(description = "사용자 이름", example = "홍길동")
            @NotBlank(message = "이름은 필수 입력값입니다.")
            String name,

            @Schema(description = "휴대폰 번호", example = "010-1234-5678")
            @Pattern(regexp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$", message = "휴대폰 번호 형식이 올바르지 않습니다.")
            String phone
    ) {
    }

    @Schema(description = "로그인 요청")
    public record LoginRequest(
            @Schema(description = "이메일 주소", example = "user@example.com")
            @NotBlank(message = "이메일은 필수 입력값입니다.")
            @Email(message = "이메일 형식이 올바르지 않습니다.")
            String email,

            @Schema(description = "비밀번호", example = "password123")
            @NotBlank(message = "비밀번호는 필수 입력값입니다.")
            String password
    ) {
    }

    @Builder
    @Schema(description = "토큰 응답")
    public record TokenResponse(
            @Schema(description = "JWT 액세스 토큰", example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
            String accessToken,
            
            @Schema(description = "JWT 리프레시 토큰", example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
            String refreshToken,
            
            @Schema(description = "토큰 타입", example = "Bearer")
            String tokenType,
            
            @Schema(description = "액세스 토큰 만료 시간(초)", example = "3600")
            Long expiresIn
    ) {
    }

    @Schema(description = "토큰 갱신 요청")
    public record TokenRefreshRequest(
            @Schema(description = "리프레시 토큰", example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
            @NotBlank(message = "리프레시 토큰은 필수 입력값입니다.")
            String refreshToken
    ) {
    }
}

EmailVerificationDto

public class EmailVerificationDto {

    @Schema(description = "이메일 인증 요청")
    public record EmailVerificationRequest(
           @Schema(description = "학교 이메일 주소", example = "student@office.skhu.ac.kr")
           @NotBlank(message = "이메일은 필수 입력값입니다.")
           @Email(message = "이메일 형식이 올바르지 않습니다.")
           String email
    ) {}

    @Schema(description = "이메일 인증 코드 확인 요청")
    public record VerificationCodeRequest(
            @Schema(description = "학교 이메일 주소", example = "student@office.skhu.ac.kr")
            @NotBlank(message = "이메일은 필수 입력값입니다.")
            @Email(message = "이메일 형식이 올바르지 않습니다.")
            String email,

            @Schema(description = "6자리 인증 코드", example = "123456")
            @NotBlank(message = "인증 코드는 필수 입력값입니다.")
            String verificationCode
    ) {}

    @Schema(description = "이메일 인증 응답")
    public record EmailVerificationResponse(
            @Schema(description = "처리 성공 여부", example = "true")
            boolean success,
            
            @Schema(description = "응답 메시지", example = "인증 이메일이 발송되었습니다.")
            String message
    ) {}
}

PasswordDto

public class PasswordDto {

    @Schema(description = "비밀번호 재설정 요청")
    public record PasswordResetRequest(
            @Schema(description = "사용자 이메일 주소", example = "user@example.com")
            @NotBlank(message = "이메일은 필수 입력값입니다.")
            @Email(message = "이메일 형식이 올바르지 않습니다.")
            String email
    ) {}

    @Schema(description = "비밀번호 재설정 검증 요청")
    public record PasswordResetVerifyRequest(
            @Schema(description = "비밀번호 재설정 토큰", example = "1234567890abcdef")
            @NotBlank(message = "토큰은 필수 입력값입니다.")
            String token,

            @Schema(description = "새 비밀번호 (최소 8자 이상)", example = "newPassword123")
            @NotBlank(message = "새 비밀번호는 필수 입력값입니다.")
            @Size(min = 8, message = "비밀번호는 최소 8자 이상이어야 합니다.")
            String newPassword
    ) {}

    @Builder
    @Schema(description = "비밀번호 재설정 응답")
    public record PasswordResetResponse(
            @Schema(description = "처리 성공 여부", example = "true")
            boolean success,
            
            @Schema(description = "응답 메시지", example = "비밀번호가 성공적으로 변경되었습니다.")
            String message
    ) {}
}

예시 이미지

profile
공부하는 초보 개발자

0개의 댓글