Skip to content

TunaForce4/tf4-order

Repository files navigation

Order-Service

5. 라이브러리 사용 이유

Querydsl

  • JPQL의 컴파일 시점 오류 확인 불가
  • 쿼리 가독성과 타입 안정성을 보장하여 유지보수 용이

7. 브랜치 및 디렉토리 구조

디렉토리 구조

Order
Product

8. 주요 기능

8) Order

기능 메서드 엔드포인트 Query Params status
주문 생성 POST /orders 201
주문 단건 조회 GET /orders/{orderId} 200
허브 주문 목록 조회 (페이지네이션) GET /orders/hubs/{hubId} page, size, sort 200
업체 주문 목록 조회 (페이지네이션) GET /orders/companies/{companyId} page, size, sort 200
주문 수정 PATCH /orders/{orderId} 204
주문 취소 PATCH /orders/{orderId}/cancel 204
주문 삭제 DELETE /orders/{orderId} 200

9) Product

기능 메서드 엔드포인트 Query Params status
상품 생성 POST /products 201
상품 단건 조회 GET /products/{productId} 200
상품 전체 목록 조회 (페이지네이션) GET /products page, size, sort, productName 200
허브 등록 상품 목록 조회 (페이지네이션) GET /products/hubs/{hubId} page, size, sort, productName 200
업체 등록 상품 목록 조회 (페이지네이션) GET /products/companies/{companyId} page, size, sort, productName 200
상품 수정 PATCH /products 204
상품 삭제 DELETE /products 200

9. 상세 업무

Order

  • 유저 권한별 각 기능 유효성 검증

    주문 생성

    주문_생성

    주문 단건 조회

    주문_단건_조회

    허브 주문 목록 조회

    허브_주문_목록_조회

    업체 주문 목록 조회

    업체_주문_목록_조회

    주문 수정/삭제

    주문_수정

Product

  • 유저 권한별 각 기능 유효성 검증

    상품 생성

    상품_생성

    상품 단건 조회

    상품_단건_조회

    허브 등록 상품 목록 조회

    허브_등록_상품_목록_조회

    업체 등록 상품 목록 조회

    업체_등록_상품_목록_조회

    상품 수정

    상품_수정

    상품 삭제

    상품_삭제

공통

  • DTO의 record 타입 사용

    • 클라이언트의 요청에 대한 불변성과 안정성을 명시
  • Pageablesort 쿼리 - 정렬 조건 타입 안정화

    • 정해진 정렬 조건만 허용 - 예기치 못한 쿼리 또는 에러 발생 방지
    • 동일한 property 정렬 시 예외 발생
    • SortType ENUM
      @Getter
      @RequiredArgsConstructor
      public enum SortType {
      
          CREATED_ASC("createdAt", Sort.Direction.ASC),
          CREATED_DESC("createdAt", Sort.Direction.DESC),
          UPDATED_ASC("updatedAt", Sort.Direction.ASC),
          UPDATED_DESC("updatedAt", Sort.Direction.DESC),
          PRICE_ASC("price", Sort.Direction.ASC),
          PRICE_DESC("price", Sort.Direction.DESC),
          ;
      
          private final String value;
          private final Sort.Direction direction;
      
          public static void validate(Sort sort) {
              Set<String> check = new HashSet<>();
      
              for (Sort.Order order : sort) {
                  if (!match(order)) {
                      throw new CustomRuntimeException(ProductException.UNSUPPORTED_SORT_TYPE);
                  }
      
                  if (!check.add(order.getProperty().toLowerCase())) {
                      throw new CustomRuntimeException(ProductException.DUPLICATED_SORT_TYPE);
                  }
              }
          }
      
          private static boolean match(Sort.Order order) {
              return Arrays.stream(SortType.values())
                      .anyMatch(sortType -> sortType.value.equalsIgnoreCase(order.getProperty()) &&
                         sortType.getDirection().equals(order.getDirection()));
          }
      }
      
  • QuerydslgetOrderSpecifier()을 통한 동적 정렬 조건 쿼리 구현

    • 클라이언트가 여러 개의 sort 쿼리를 넘기도록 하여 .orderBy()에 적용
      private OrderSpecifier<?>[] getOrderSpecifiers(Sort sort) {
        List<OrderSpecifier<?>> orderSpecifiers = new ArrayList<>();
      
        for (Sort.Order sortOrder : sort) {
            Order order = sortOrder.isAscending() ? Order.ASC : Order.DESC; // sort 쿼리 내 정렬 방향을 Order 객체로 파싱 
            PathBuilder<Product> pathBuilder
                    = new PathBuilder<>(product.getType(), product.getMetadata()); // sort 쿼리 내 정렬 값을 QClass 내 필드값에 해당하는 값으로 매핑  
      
            orderSpecifiers.add(new OrderSpecifier<>(order, pathBuilder.getString(sortOrder.getProperty())));
        }
      
        return orderSpecifiers.toArray(new OrderSpecifier[0]);
      }
      

11. 트러블 슈팅

OpenFeign Invalid HTTP method: PATCH
  1. 문제 상황
    openfeign_trouble_1 openfeign_trouble_2
  • Order서비스에서 Product서비스로 주문 상품 수량 수정이나 주문 취소시 차감했던 상품의 재고를 다시 변경하기 위해 PATCH 메소드 사용
  • OpenFeign은 HTTP 요청을 추상화하여 메소드 호출로 REST API 호출 가능하도록 지원해주는데 HTTP 기본 구현체가 추가 의존성 없이 작동하도록 설계됨
  • HttpURLConnection은 별도 라이브러리 의존 없이 사용 가능하므로 OpenFeign에서 사용
  • PATCH는 비교적 최신 기능이라 HttpURLConnection에서 지원이 안되는 것
  1. 해결방안
  • 외부 HTTP 클라이언트 라이브러리를 사용하여 해결(커스텀)
    • ApachHttpClient, OkHttpClient
  • 하지만 각 서비스 간 내부 통신이므로 Restful 규약을 준수할 필요는 없다고 생각함
  1. 최종 결정
  • PATCH -> POST 변경

12. 회고

최우탁

  • 권한별 기능 설계 및 구현에 시간을 너무 사용하여 OpenFeign 통신 장애 대응 로직을 충분히 구현하지 못해 아쉽다.
  • 각 기능의 최적화나 고도화를 진행하지 못한 점도 개선할 필요가 있다.
  • 다음 프로젝트에서는 설계 단계에서 서비스의 전체적인 도메인에 대한 이해를 충분한 회의나 지식 공유등을 통해 정리하고 가는 것이 좋을 것 같다.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages