π[Backend Development] Request/Response DTOμ μμΈ κ΅¬μ‘°.
DTOμ μμΈ κ΅¬μ‘°λ βμ΄λ€ μν μ νλλβ μ λ°λΌ λ¬λΌμ§λλ€.
Request DTOλ λ°μ΄ν°λ₯Ό λ°μ κ²μ¦νλ κ²μ, Response DTOλ λ°μ΄ν°λ₯Ό 보기 μ’κ² κ°κ³΅νμ¬ λ³΄μ¬μ£Όλ κ²μ μ΄μ μ λ§μΆ₯λλ€.
π¦ Request DTOμ μμΈ κ΅¬μ‘°.
Request DTOλ ν΄λΌμ΄μΈνΈλ‘λΆν° λ€μ΄μ€λ λ°μ΄ν°λ₯Ό μμ νκ² λ°μλ΄κΈ° μν ꡬ쑰λ₯Ό κ°μ§λλ€.
-
νλ (Fields)
- API μμ² λ³Έλ¬Έ(Request Body)μ JSON
key
μ μΌμΉνλ λ©€λ² λ³μλ€λ‘ ꡬμ±λ©λλ€.
- API μμ² λ³Έλ¬Έ(Request Body)μ JSON
-
κ²μ¦ μ΄λ
Έν
μ΄μ
(Validation Annotations)
-
@NotBlank
,@NotNull
,@Size
,@Pattern
λ±jakarta.validation
μ΄λ Έν μ΄μ μ μ¬μ©νμ¬, λΉμ¦λμ€ λ‘μ§μ λλ¬νκΈ° μ μ λ°μ΄ν°κ° μ ν¨νμ§ κ²μ¬ν©λλ€.- μ΄κ²μ΄ Request DTOμ κ°μ₯ μ€μν νΉμ§μ λλ€.
-
-
κΈ°λ³Έ μμ±μμ Getter
- JSON λ°μ΄ν°λ₯Ό κ°μ²΄λ‘ λ³ν(Deserialization)νκΈ° μν΄ Lombokμ
@NoArgsConstructor
μ@Getter
λ₯Ό μ£Όλ‘ μ¬μ©ν©λλ€.
- JSON λ°μ΄ν°λ₯Ό κ°μ²΄λ‘ λ³ν(Deserialization)νκΈ° μν΄ Lombokμ
μ½λ μμ : ProductCreateRequestDto.java
@Getter
@NoArgsConstructor // JSON λ³νμ μν κΈ°λ³Έ μμ±μ
public class ProductCreateRequestDto {
@NotBlank(message = "μνλͺ
μ νμμ
λλ€.")
@Size(max = 100, message = "μνλͺ
μ 100μλ₯Ό λμ μ μμ΅λλ€.")
private String productName;
@NotNull(message = "νλ§€κ°λ νμμ
λλ€.")
@Positive(message = "νλ§€κ°λ 0λ³΄λ€ μ»€μΌ ν©λλ€.")
private BigDecimal productSaleCost;
// ... μμ²μ νμν λ€λ₯Έ νλμ κ²μ¦ κ·μΉλ€ ...
}
π¦ Response DTOμ μμΈ κ΅¬μ‘°.
Response DTOλ μλ²μ μ²λ¦¬ κ²°κ³Όλ₯Ό ν΄λΌμ΄μΈνΈμκ² λͺ ννκ³ μ¬μ©νκΈ° νΈν ννλ‘ λ³΄μ¬μ£ΌκΈ° μν ꡬ쑰λ₯Ό κ°μ§λλ€.
-
νλ (Fields)
-
Entity
μ λ°μ΄ν°λ₯Ό κ·Έλλ‘ λ³΄μ¬μ£ΌκΈ°λ νκ³ , μ¬λ¬Entity
μ μ 보λ₯Ό μ‘°ν©νκ±°λService
μμ κ³μ°λ κ°μ ν¬ν¨νκΈ°λ ν©λλ€. - μ:
margin
,totalStockCount
-
-
λΆλ³μ± (Immutability)
- μλ΅μΌλ‘ λκ°λ λ°μ΄ν°κ° μ€κ°μ λ³κ²½λμ§ μλλ‘
final
νλμ μμ±μ(@Builder
νμ©)λ₯Ό μ¬μ©νμ¬ λΆλ³ κ°μ²΄λ‘ λ§λλ κ²μ΄ μ’μ ν¨ν΄μ λλ€.setter
λ μ¬μ©νμ§ μμ΅λλ€.
- μλ΅μΌλ‘ λκ°λ λ°μ΄ν°κ° μ€κ°μ λ³κ²½λμ§ μλλ‘
-
μ μ ν©ν 리 λ©μλ (Static Factory Method)
-
Entity
κ°μ²΄λ₯Ό DTO κ°μ²΄λ‘ λ³ννλ λ‘μ§μ DTO λ΄λΆμ μ μ λ©μλ(e.g,from(Product product)
)λ‘ λ§λ€μ΄λλ©΄,Service
κ³μΈ΅μ μ½λλ₯Ό λ κΉλνκ² μ μ§ν μ μμ΅λλ€.
-
μ½λ μμ: ProductResponseDto.java
@Getter
public class ProductResponseDto {
private final Long productId;
private final String productName;
private final BigDecimal fianlSalePrice; // κ³μ°λ μ΅λ νλ§€κ°
private final int totalStockCount; // κ³μ°λ μ΄μ¬κ³
// DTOλ λΆλ³μ±μ μν΄ Builderλ₯Ό ν΅ν μμ±μλ§ νμ©
@Builder
private ProductResponseDto(Long productId, String productName, BigDecimal finalSalePrice, int totalStockCount) {
this.productId = productId;
this.productName = productName;
this.finalSalePrice = finalSalePrice;
this.totalStockCount = totalStockCount;
}
// Entityλ₯Ό DTOλ‘ λ³ννλ μ μ ν©ν 리 λ©μλ
public static ProductResponseDto from(Product product, int totalStockCount) {
return ProductResponseDto.builder()
.productId(product.getProductId())
.productName(product.getProductName())
.finalSalePrice(calculateFinalPrice(product.getProductSaleCost(), product.getProductDiscountRate()))
.totalStockCount(totalStockCount)
.build();
}
private static BigDecimal calculateFinalPrice(BigDecimal saleCost, Integer discountRate) {
// ... κ°κ²© κ³μ° λ‘μ§ ...
}
}