BACKEND/Spring

SpringBoot API ์ฃผ์˜ํ•  ์ 

์†ก์ด ๐Ÿซง 2022. 1. 27. 12:44

- ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ง์ ‘ ๋…ธ์ถœํ•˜์ง€ ๋ง๊ณ  DTO ๋ณ€ํ™˜ํ•ด๋ผ

- ์ง€์—ฐ ๋กœ๋”ฉ(LAZY)๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ฆ‰์‹œ ๋กœ๋”ฉ(EARGER)๋กœ ์„ค์ •ํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ์ฆ‰์‹œ ๋กœ๋”ฉ ๋•Œ๋ฌธ์— ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ํ•„์š”์—†๋Š” ๊ฒฝ์šฐ์—๋„ 

๋ฐ์ดํ„ฐ๋ฅผ ํ•ญ์ƒ ์กฐํšŒํ•ด์„œ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•ญ์ƒ ์ง€์—ฐ๋กœ๋”ฉ์„ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜๊ณ , ์„ฑ๋Šฅ ์ตœ์ ํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ํŽ˜์น˜์กฐ์ธ์„ ์‚ฌ์šฉํ•ด๋ผ! (+์ง€์—ฐ๋กœ๋”ฉ์˜ ๊ฒฝ์šฐ ์—ฐ๊ด€๋œ ์—”ํ‹ฐํ‹ฐ๋Š” ํ”„๋ก์‹œ๋กœ ์„ค์ •๋˜์–ด์žˆ๊ณ  getName()๊ณผ ๊ฐ™์ด ์ง์ ‘ ํ˜ธ์ถœํ•ด์•ผ LAZY๊ฐ€ ๊ฐ•์ œ ์ดˆ๊ธฐํ™”๋จ) 

 

Controller API ์˜ˆ์‹œ

@GetMapping("/api/v3/orders")
public List<OrderDto> ordersV3() {
    List<Order> orders = orderRepository.findAllWithItem();
    List<OrderDto> result = orders.stream()
            .map(order -> new OrderDto(order))
            .collect(Collectors.toList());

    return result;
@Data
    static class OrderDto {

        private Long orderId;
        private String name;
        private OrderStatus orderStatus;
        private Address address; // ๊ฐ’ ํƒ€์ž…์€ ๋…ธ์ถœํ•ด๋„ OK
        private List<OrderItemDto> orderItems; // OrderItemDto๋กœ ๋งคํ•‘(์—”ํ‹ฐํ‹ฐ ์™ธ๋ถ€์— ๋…ธ์ถœ ๋ง‰๊ธฐ ์œ„ํ•ด)

        public OrderDto(Order o) {
            orderId = o.getId();
            name = o.getMember().getName(); //LAZY ์ดˆ๊ธฐํ™”
            orderStatus = o.getStatus();
            address = o.getDelivery().getAddress(); // LAZY ์ดˆ๊ธฐํ™”
            o.getOrderItems().stream().forEach(order -> order.getItem().getName());
            //OrderItem์„ OrderItemDto๋กœ ๋ณ€ํ™˜
            orderItems = o.getOrderItems().stream()
                        .map(orderItem -> new OrderItemDto(orderItem))
                        .collect(Collectors.toList());
        }
    }

    @Getter
    static class OrderItemDto{

        private String itemName;
        private int orderPrice;
        private int count;

        public OrderItemDto(OrderItem orderItem) {
            itemName = orderItem.getItem().getName();
            orderPrice = orderItem.getOrderPrice();
            count = orderItem.getCount();
        }
    }
}

- DTO ํด๋ž˜์Šค์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์—”ํ‹ฐํ‹ฐ๋กœ ๋„˜๊ธธ ์ˆ˜ ์žˆ์Œ (But, jpql์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ์—์„œ๋Š” ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์‹๋ณ„์ž๋กœ ์ธ์‹๋˜๊ธฐ๋•Œ๋ฌธ์— ์•ˆ๋จ!)

- OrderDto์— ์กด์žฌํ•˜๋Š” OrderItems๋„ ์—”ํ‹ฐํ‹ฐ์ด๋ฏ€๋กœ ์™ธ๋ถ€ ๋…ธ์ถœ์„ ๋ง‰๊ธฐ ์œ„ํ•ด DTO๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ์–ด์•ผํ•จ 

 

 

** ์กฐํšŒ ์„ฑ๋Šฅ ์ตœ์ ํ™”

- ToOne ๊ด€๊ณ„์—์„œ๋Š” fetch join์œผ๋กœ ํ•œ๋ฒˆ์— ์ „๋ถ€ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ์„ฑ๋Šฅ์— ์ข‹๋‹ค.

- ToMany ๊ด€๊ณ„์—์„œ๋Š” ToOne ์ธ๊ฒƒ๋“ค๋งŒ fetch join์œผ๋กœ ํ•˜๊ณ  ์ปฌ๋ ‰์…˜์€ batch size๋กœ ํ†ต์ œํ•˜์ž!! 

   (ํŽ˜์ด์ง•์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•จ)

   (ํŽ˜์น˜์กฐ์ธ์œผ๋กœ ํ•˜๋Š” ๊ฒƒ์— ๋น„ํ•ด ์ฟผ๋ฆฌ ์ˆ˜๋Š” ์ฆ๊ฐ€ํ•˜์ง€๋งŒ DB ๋ฐ์ดํ„ฐ ์ „์†ก๋Ÿ‰์ด ๊ฐ์†Œํ•œ๋‹ค) 

   (batch size๋Š” 100~1000 ์ •๋„๊ฐ€ ๊ฐ€์žฅ ์ข‹๋‹ค) 

   (1000๊ฐœ๊ฐ€ ์ฟผ๋ฆฌ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ์ƒ ๊ฐ€์žฅ ์ข‹์ง€๋งŒ DB์— ์ˆœ๊ฐ„ ๋ถ€ํ•˜๊ฐ€ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค)