IT/Spring Cloud

Order Service

김 정 환 2021. 12. 15. 23:41
반응형

앞으로 구현할 주문 서비스의 개요입니다.

 

 

APIs입니다.

기능 마이크로서비스 URI (API Gateway  사용시) HTTP Method
사용자 별 상품 주문 Orders Microservice /order-sercie/{user_id}/orders POST
사용자 별 주문 내역 조회 Orders Microservice /order-service/{user_id}/orders GET

 

 

프로젝트를 생성하겠습니다. 아래 Dependencies를 추가합니다.

  • Spring Boot DevTools : 코드가 변경되면 자동으로 애플리케이션 재시작 등 하기 위해서 추가 ... 참조
  • Lombok : 코드 작성을 편하게 하기 위해서 추가 ... 참조
  • Spring web : REST API 작성하기 위해서 추가
  • Eureka Discovery Client : Eureka discovery 사용하기 위해서 추가
  • H2 Database
  • Spring Data JPA

 

 

필요한 dependencies를 추가하겠습니다. 아래 dependancies를 pom.xml에 추가합니다.

        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.4.4</version>
        </dependency>

 

 

소스코드

프로젝트 내의 파일 위치를 아래와 같습니다.

 

application.yaml 설정은 아래와 같습니다.

server:
  port: 0

spring:
  application:
    name: order-service
  h2:
    console:
      enabled: true
      settings:
        web-allow-others: true
      path: /h2-console

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    generate-ddl: true
    database: h2
    defer-datasource-initialization: true

  datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:testdb


eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
    hostname: localhost

  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka


logging:
  level:
    com.example.orderservice: DEBUG

 

DB와 연동하기 위한 데이터를 다룰 OrderEntity.java를 만들어 줍니다.

@Data
@Entity
@Table(name = "orders")
public class OrderEntity implements Serializable { // Serialization : 데이터를 저장 또는 전송하기 적합한 형태로 바꿔주기

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

    @Column(nullable = false, length = 120, unique = true)
    private String productId;

    @Column(nullable = false)
    private Integer qty;

    @Column(nullable = false)
    private Integer unitPrice;

    @Column(nullable = false)
    private Integer totalPrice;


    @Column(nullable = false)
    private String userId;

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

    @Column(nullable = false, updatable = false, insertable = false)
    @ColumnDefault(value = "CURRENT_TIMESTAMP")
    private Date createAt;
}

 

DB query를 만들어줄 OrderRepository.java를 만들어 줍니다.

public interface OrderRepository extends CrudRepository<OrderEntity, Long> {
    OrderEntity findByOrderId(String orderId);
    Iterable<OrderEntity> findByUserId(String userId);
}

 

Controller - Service - JPA 사이를 이동할 데이터 객체인 OrderDto.java를 만들어 줍니다.

@Data
public class OrderDto implements Serializable {
    private String productId;
    private Integer qty;
    private Integer unitPrice;
    private Integer totalPrice;

    private String orderId;
    private String userId;
}

 

유저가 보낸 request의 body를 받아서 담을 RequestOrder.java를 만들어 줍니다.

@Data
public class OrderDto implements Serializable {
    private String productId;
    private Integer qty;
    private Integer unitPrice;
    private Integer totalPrice;

    private String orderId;
    private String userId;
}

 

유저가 보낸 요청에 대한 응답 값을 담아서 보내줄 ResponseOrder.java를 만들어 줍니다.

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseOrder {
    private String productId;
    private Integer qty;
    private Integer unitPrice;
    private Integer totalPrice;
    private Date createAt;

    private String orderId;
}

 

서비스를 만들어 보겠습니다. OrderService.java 인터페이스를 만들어 원하는 서비스를 만들어 줍니다.

public interface OrderService {

    // 구현할 서비스

    // 주문 생성
    OrderDto createOrder(OrderDto orderDto);

    // 주문 번호로 주문 내역 조회
    OrderDto getOrderByOrderId(String orderId);

    // 사용자 Id로 전체 주문 내역 조회
    Iterable<OrderEntity> getOrdersByUserId(String userId);
}

 

서비스를 구현해 줍니다. OrderServiceImpl.java

@Service
public class OrderServiceImpl implements OrderService{

    OrderRepository orderRepository;

    @Autowired
    public OrderServiceImpl(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    @Override
    public OrderDto createOrder(OrderDto orderDto) {
        orderDto.setOrderId(UUID.randomUUID().toString());
        orderDto.setTotalPrice(orderDto.getQty() * orderDto.getUnitPrice());

        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        OrderEntity orderEntity = mapper.map(orderDto, OrderEntity.class);

        orderRepository.save(orderEntity);

        OrderDto returnValue = mapper.map(orderEntity, OrderDto.class);

        return returnValue;
    }

    @Override
    public OrderDto getOrderByOrderId(String orderId) {

        OrderEntity orderEntity = orderRepository.findByOrderId(orderId);

        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        OrderDto orderDto = mapper.map(orderEntity, OrderDto.class);

        return orderDto;
    }

    @Override
    public Iterable<OrderEntity> getOrdersByUserId(String userId) {
        return orderRepository.findByUserId(userId);
    }
}

 

이제 컨트롤러를 만들어 줍니다. OrderController.java

@RestController
@RequestMapping("/order-service")
public class OrderController {

    Environment env;
    OrderService orderService;

    public OrderController(Environment env, OrderService orderService) {
        this.env = env;
        this.orderService = orderService;
    }

    @GetMapping("/health_check")
    public String status(){
        return String.format("It's Working in Catalog Service on PORT %s",
                env.getProperty("local.server.port"));
    }

    @PostMapping("/{user_id}/orders")
    public ResponseEntity<ResponseOrder> createOrder(@PathVariable("user_id") String userId,
                                                     @RequestBody RequestOrder order){

        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

        OrderDto orderDto = mapper.map(order, OrderDto.class);
        orderDto.setUserId(userId);
        OrderDto createdOrder = orderService.createOrder(orderDto);

        ResponseOrder responseOrder = mapper.map(createdOrder, ResponseOrder.class);

        return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder);
    }

    @GetMapping("/{user_id}/orders")
    public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("user_id") String userId){
        Iterable<OrderEntity> orderList = orderService.getOrdersByUserId(userId);

        List<ResponseOrder> result = new ArrayList<>();

        orderList.forEach(v -> {
            result.add(new ModelMapper().map(v, ResponseOrder.class));
        });

        return ResponseEntity.status(HttpStatus.OK).body(result);
    }
}

 

POSTMAN으로 확인해 보겠습니다.

 

주문을 등록해 보겠습니다. 아래 user_id는 user-service에서 유저를 등록할 때 생성되는 값 입니다. body를 넣어서 보내줍니다. 같은 user_id로 여러 개 주문(보내)합니다. POST 방식입니다.

 

같은 URL인데 GET 방식으로 보내면, 유저가 주문한 목록을 전부 보여줍니다.

 

H2 데이터베이스에도 저장되어 있습니다.

 

끝.

반응형

'IT > Spring Cloud' 카테고리의 다른 글

Configuration Service  (0) 2021.12.30
User Microservice - 회원 로그인  (0) 2021.12.17
Catalogs Microservice  (0) 2021.12.15
User Microservice - 회원 등록  (0) 2021.12.13
애플리케이션 개요  (0) 2021.12.08