https://jangcenter.tistory.com/38에서 이어짐
Spring Cloud(MSA) 실습 - 웹 쇼핑몰 2. 카달로그 서비스
https://jangcenter.tistory.com/35에서 이어짐 Spring Cloud(MSA) 실습 - 웹 쇼핑몰 1. 기본 설정과 회원 서비스 실제 MSA를 위한 실습 MSA의 동작 학습/응용이 목적이기 때문에 상세한 기능 구현, 다자인은 신경..
jangcenter.tistory.com
주문 서비스(orders Microservice) 설계
기능 | apigateway-service URI | Method |
사용자 상품 주문 등록 | /order-service/{userId}/orders | POST |
사용자 상품 주문 내역 조회 | /order-service/{userId}/orders | GET |
주문 서비스 프로젝트 생성 및 기본설정

* h2의 버전 변경 자동으로 DB생성을 위해, modelmapper 의존성 추가
# porm.xml ....... <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> <version>1.3.176</version> </dependency> <dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>2.3.8</version> </dependency> </dependencies> .......
application.yml작성
# order-service/application.yml server: port: 0 spring: application: name: order-service h2: console: enabled: true settings: web-allow-others: true path: /h2-console datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:testdb username: sa jpa: hibernate: ddl-auto: update-drop eureka: instance: instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}} client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://localhost:8761/eureka
order-service를 apigateway-service에 등록
어플리케이션 이름으로 접근/라우팅을 위해 apigateway-service에 등록
apigateway-service의 application.yml에 order-service의 라우팅 정보를 추가
# apigateway-service/application.yml .... routes: .... - id: order-service predicates: - Path=/order-service/** uri: lb://ORDER-SERVICE ....
order-service 기능 구현
DB를 위한 VO, DTO, JPA 클래스
VO 패키지
// RequestOrder.java // 주문에 대한 요청처리 package com.example.MSA_web.vo; import lombok.Data; @Data public class RequestOrder { private String productId; private Integer qty; private Integer unitPrice; } ----------------------------------------------------------------------------------------------- // ResponseOrder.java // 응답 처리 package com.example.MSA_web.vo; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; @Data @JsonInclude(JsonInclude.Include.NON_NULL) public class ResponseOrder { private String productId; private Integer qty; private Integer unitPrice; private Integer totalPrice; private String orderId; private String userId; }
DTO 패키지
// OrderDto.java package com.example.MSA_web.dto; import java.io.Serializable; import lombok.Data; @Data public class OrderDto implements Serializable { private String productId; private Integer qty; private Integer unitPrice; private Integer totalPrice; private String orderId; private String userId; }
JPA 패키지
// OrderEntity.java // 실제 DB 데이터 package com.example.MSA_web.jpa; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.annotations.ColumnDefault; import lombok.Data; @Data @Entity @Table(name="orders") public class OrderEntity { @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 createdAt; } ---------------------------------------------------------------------------------------------- // OrderRepository.java package com.example.MSA_web.jpa; import org.springframework.data.repository.CrudRepository; public interface OrderRepository extends CrudRepository<OrderEntity, Long> { OrderEntity findByOrderId(String orderId); Iterable<OrderEntity> findByUserId(String userId); }
모듈 기능 구현
controller
// OrderController.java package com.example.MSA_web.controller; import java.util.ArrayList; import java.util.List; import org.apache.catalina.mapper.Mapper; import org.modelmapper.ModelMapper; import org.modelmapper.convention.MatchingStrategies; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.MSA_web.dto.OrderDto; import com.example.MSA_web.jpa.OrderEntity; import com.example.MSA_web.service.OrderService; import com.example.MSA_web.vo.RequestOrder; import com.example.MSA_web.vo.ResponseOrder; @RequestMapping("/order-service") @RestController public class OrderController { Environment env; OrderService orderService; @Autowired public OrderController(Environment env, OrderService orderService) { this.env = env; this.orderService = orderService; } @GetMapping("/health_check") public String healthCheck() { // 할당받은 포트번호 출력 return String.format("OK ... Port num = %s", env.getProperty("local.server.port")); } @PostMapping("/{userId}/orders") public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId, @RequestBody RequestOrder order){ ModelMapper mapper=new ModelMapper(); // ResponseOrder -> OrderDto mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); OrderDto orderDto =mapper.map(order, OrderDto.class); // 본문에 저장되지 않은 유저 정보 저장 orderDto.setUserId(userId); // create 서비스 호출 OrderDto resultDto=orderService.createOrder(orderDto); //OrderDto -> ResponseOrder ResponseOrder responseOrder=mapper.map(resultDto, ResponseOrder.class); return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder); } @GetMapping("/{userId}/orders") public ResponseEntity<List<ResponseOrder>> getOrders(@PathVariable("userId") String userId){ Iterable<OrderEntity> orderList= orderService.getOrdersByUserId(userId); List<ResponseOrder> resultList=new ArrayList<>(); orderList.forEach(v->{ resultList.add(new ModelMapper().map(v, ResponseOrder.class)); }); return ResponseEntity.status(HttpStatus.OK).body(resultList); } }
최종 테스트
각각의 연관관계 때무에 Eureka server -> apigateway-service -> user/catalog/order service 순으로 실행
Eureka 서버 확인
Eureka server, apigateway, user/catalog/order service가 전부 동작중인 것을 확인

각 서비스의 MSA 동작 확인 및 시나리오가 성공하는지 테스트
* 사용자 등록 -> 사용자 조회 -> 상품 조회 -> 주문 등록 -> 주문 조회 -> 추가 주문 -> 주문 조회
POST를 이용해 DB에 저장하기 편하게 하기 위해 Postman을 사용
사용자 등록
POST -- http://localhost:8000/user-service/users
{ "email": "tester@test.com", "name": "테스터", "pwd": "12341234" }

사용자 조회
GET -- http://localhost:8000/user-service/users

상품 조회
GET -- http://localhost:8000/catalog-service/catalogs

주문 등록
POST -- http://localhost:8000/order-service/USER_ID/orders
{ "productId": "CAT_01", "unitPrice": 1000, "qty": 20 }

주문 조회
GET -- http://localhost:8000/order-service/USER_ID/orders

추가 주문
POST -- http://localhost:8000/order-service/USER_ID/orders
{ "productId": "CAT_02", "unitPrice": 1500, "qty": 10 }

주문 조회
GET -- http://localhost:8000/USER_ID/orders

'Spring Cloud' 카테고리의 다른 글
Spring Cloud(MSA) 실습 - 웹 쇼핑몰 2. 카달로그 서비스 (0) | 2021.09.16 |
---|---|
Spring Cloud(MSA) 실습 - 웹 쇼핑몰 1. 기본 설정과 회원 서비스 (0) | 2021.09.15 |
Spring Cloud - 서비스 디스커버리 (0) | 2021.09.14 |
댓글