[내일배움캠프 본캠프] 13일 차 TIL 상품-주문 MSA 프로젝트

2026. 2. 22. 23:03·내배캠

13일 차 TIL

MSA를 완강하며, 전체적인 연동을 다시 해보고
간단한 상품-주문도메인으로 구성된 프로젝트를 구현해 봤다.

 

MSA의 사용법도 중요하지만..!

기본적인 CRUD와 디테일이 다시 한번 중요하다고 느껴졌다.

 

MSA의 설정법 자체는 한 번 익히고 나면 계속 보면서 따라 하면 되지만
강의에서는 CRUD의 성능을 높이고 각 데이터에 대한 검증, 권한, 보안등 여러 요소들을 신경 써서 한 것이 보였다.

MSA  마무리 프로젝트

- 구현해야 하는 상품-주문 프로젝트

상품-주문 MSA 프로젝트

 

프로젝트 설계)
boot 버전 : 3.5.11
springCloudVersion : 2025.0.1

사용한 라이브러리)

  1. Spring Web
  2. Lombok
  3. Mysql Driver
  4. Spring Data JPA
  5. Spring Security
  6. Eureka Server
  7. Eureka Discovery Client
  8. OpenFeign
  9. Config Server
  10. Config Client
  11. Reactive Gateway
  12. Spring Boot Actuator
  13. io.jsonwebtoken:jjwt:0.12.6
포트번호)
유레카 서버 : 19090
컨피그 서버 : 18080
게이트웨이 : 19091
주문 : 19092
상품 : 19093, 19094
유저 : 19095
eureka server에 client로 등록
1. gateway
2. config server
3. auth
4. product
5. order
config server에 client로 등록
1. gateway
2. auth
3. product]
4. order


config server는 auth, product, order의 db정보를 관리하고
gateway의 라우팅정보를 관리한다.

그리고 auth와 gateway에서는 jwt secretkey도 추가로 관리해 준다.

로그인 및 회원가입

먼저, Auth 서비스에서 간단하게 유저명과 비밀번호로 회원가입 및 로그인 기능을 구현했다.

회원가입 시 User 테이블에 저장,

role은 member를 기본적으로 설정
이후 manager로 변경하는 로직을 추가할 예정이다.

 

UserDetails에 User 객체를 담고, UserDetailsServiceImpl로 생성해서 로그인했고
로그인 성공 시 JWT를 발급해서 응답 body에 넣어 반환했다.


/auth/signUp, /auth/signIn
은 Auth 앱과 Gateway에서 모두 필터를 거치지 않고 통과시켰다.

 

Gateway에서 Pre필터 방식으로 JWT를 검증해 로그인 유무를 판별한다.

상품 관리

Eureka와 config에 client로 등록한다.

- application.yaml

spring:
  application:
    name: product-service
  config:
    import: "configserver:"
  cloud:
    config:
      discovery:
        enabled: true
        service-id: config-server
server:
  port: 19093
eureka:
  client:
    service-url:
      defaultZone: http://localhost:19090/eureka/

 

그리고 config server에서 받아오는 설정이다.
- product-service.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/msa_product?serverTimezone=Asia/Seoul&useSSL=false
    username: root
    password: mysql1234
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        format_sql: true
      database-platform: org.hibernate.dialect.MySQLDialect

이후 CRUD와 Search 구현은 모놀리틱 프로젝트와 동일하다.

 

- 상품 삭제 시, 실제로 삭제하지 않고 deletedAt에 현재 시간을 적어줬다.

private Product getProductById(Long id){
    Product product = productRepository.findById(id)
            .orElseThrow(()->new IllegalArgumentException("해당 ID의 상품이 없습니다."));

    if(product.getDeletedAt() != null){
        throw new IllegalArgumentException("삭제된 상품입니다.");
    }

    return product;
}

주문 관리

주문관리도 상품처럼 config과 eureka에 client로 동일하게 등록한다.

 

주문 엔티티는 상품명과 수량
pk필드와 삭제표시용 필드로 구성했다.

Order 파트에서는 주문을 진행할 때, 상품을 조회하는 로직이 필요하다.
이때 FeignClient가 사용된다.

 

- FeignClient를 사용한 인터페이스

package com.spring_cloud.eureka.client.order.client;

import com.spring_cloud.eureka.client.order.dto.ProductResponseDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

@FeignClient(name = "product-service")
public interface ProductClient {
    @GetMapping("/products")
    List<ProductResponseDto> getProducts();

    @GetMapping("/products/{id}")
    ProductResponseDto getProduct(@PathVariable("id") Long id);
}

client 패키지 아래에 작성하였다.

ProductClient 인터페이스로 아래의 Product 컨트롤러의 메서드를 가져올 수 있다.

 

- ProductController의 상품목록을 가져오는 메서드

@GetMapping
public List<ProductResponseDto> getProducts(){
    return productService.getProducts();
}

 

- Order 컨트롤러에서 주문을 생성하는 메서드

@PostMapping
public ResponseEntity<?> createOrder(@RequestBody OrderReqeustDto requestDto, @RequestParam("productId") Long productId) {
    return ResponseEntity.ok(orderService.createOrder(requestDto,productId));
}

컨트롤러에서 주문생성 메서드를 호출하고,
Order의 서비스 레이어에서 사용된다.

 

- Order 서비스레이어에서 주문을 생성하는 메서드

public class OrderService {
    private final OrderRepository orderRepository;
    private final ProductClient productClient;

    public OrderResponseDto  createOrder(OrderReqeustDto requestDto, Long productId) {
        ProductResponseDto product = productClient.getProduct(productId);
        Order order = new Order(product.getProductName(),requestDto.getQuantity());
        orderRepository.save(order);
        return new OrderResponseDto(productId,product.getProductName(),requestDto.getQuantity());
    }
    // ...그 외 RUD + Search 기능들
}

ProductClient를 주입받아
Product를 읽어올 때 사용한다.

 

받아온 Product를 Dto로 변환해서 저장하고, Order를 생성할 때 상품명을 파라미터로 넘겨준다.

 

나머지 로직은 모놀리틱 프로젝트와 동일하게 진행했다.

강의에서 진행한 방식

패키지구조는 각 앱에서 2개의 패키지로 나눠 관리했다.

 

예를 들어, product service라면
core와 products패키지로 나누고

 

core패키지 안
도메인 패키지에 product 엔티티

client 패키지에 외부 호출 인터페이스와 반환받을 사용할 DTO

그 외 enum 같은 도메인 관련 패키지들이 들어간다.

 

products패키지에 나머지 컨트롤러 서비스 리포지 dto들을 구성한다.

 

검색 기능은 QueryDSL을 사용해서, 여러 개의 필터링을 한 번에 했다. ( JPA는 각각 따로 만들어야 함 )

gateway로부터 user정보를 exchange 안에 헤더로 넣고,
헤더에서 그 값을 받아와서 role을 통해 권한에 따라 실행했다.

 

order에서 주문을 생성할 때, 주문 안에 상품이 있는지 없는지 for문을 통해 체크했다.

'내배캠' 카테고리의 다른 글

[내일배움캠프 본캠프] 14일 차 TIL Layered Architecture  (0) 2026.02.23
[내일배움캠프 과제] MSA 강의 정리  (0) 2026.02.23
[내일배움캠프 본캠프] 12일 차 TIL MSA  (0) 2026.02.21
[내일배움캠프 본캠프] 11일 차 TIL MSA, Git flow  (0) 2026.02.20
[내일배움캠프 본캠프] 10일 차 TIL Spring AI  (0) 2026.02.19
'내배캠' 카테고리의 다른 글
  • [내일배움캠프 본캠프] 14일 차 TIL Layered Architecture
  • [내일배움캠프 과제] MSA 강의 정리
  • [내일배움캠프 본캠프] 12일 차 TIL MSA
  • [내일배움캠프 본캠프] 11일 차 TIL MSA, Git flow
MvA
MvA
백엔드 개발자 김재현입니다. 주로 공부하면서 느낀점을 기록합니다.
  • MvA
    Man vs Ai
    MvA
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • Java (6)
      • Python (8)
        • 딥러닝 (1)
        • 머신러닝 (7)
      • JavaScript (2)
      • 내배캠 (60)
      • 개인 프로젝트 (11)
      • 책 후기 (5)
      • 기타 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    머신러닝
    배포
    Riot API
    내일배움캠프
    딥러닝
    TiL
    아키텍처
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
MvA
[내일배움캠프 본캠프] 13일 차 TIL 상품-주문 MSA 프로젝트
상단으로

티스토리툴바