Cloud/MSA

[MSA] MicroService 구현(상품 서비스)

문승주 2024. 11. 27. 21:20
반응형

본 내용은 인프런의 이도원 님의 강의 "Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)" 내용을 바탕으로 정리한 내용입니다.

 

CatalogService 생성

  • Spring Boot : 3.2.6
  • Java : 17
  • Project Name : CatalogService
  • Dependencies
    • Spring Boot DevTools
    • Lombok
    • Spring Web
    • Spring Data JPA
    • Eureka Discovery Client
    • ModelMapper

CatalogService 기능

  • 상품 목록 조회

설정 파일 수정

pom.xml 수정

<dependency>  
    <groupId>org.modelmapper</groupId>  
    <artifactId>modelmapper</artifactId>  
    <version>2.3.8</version>  
</dependency>
  • ModelMapper 추가

application.yml 수정

server:  
  port: 0 # port  

spring:  
  application:  
    name: CatalogService  
  datasource:  
    driverClassName: org.mariadb.jdbc.Driver  
    url: jdbc:mariadb://localhost:3306/shop_db?characterEncoding=UTF-8&serverTimezone=UTC  
    username: root  
    password: 1234  
  jpa:  
    hibernate:  
      #ddl-auto: update  
      ddl-auto: create-drop  
    properties:  
      hibernate:  
        show_sql: true  
        format_sql: true  
        use_sql_comments: true  
eureka:  
  client:  
    service-url:  
      defaultZone: http://localhost:8761/eureka  

logging:  
  level:  
    com.example.CatalogService: DEBUG
  • Dynamic Port 설정: server.port=0 (애플리케이션 시작 시 랜덤 포트 할당)
  • Eureka 클라이언트 설정: eureka.client.service-url.defaultZone=http://localhost:8761/eureka
  • JPA 설정
    • Hibernate DDL 자동 실행: ddl-auto=create-drop (애플리케이션 실행 시 DB 테이블 초기화)
    • SQL 출력: hibernate.show_sql=true,hibernate.format_sql=true

JPA 관련 파일 생성

CatalogEntity 생성

package com.example.CatalogService.jpa;  

import jakarta.persistence.*;  
import lombok.Data;  
import org.hibernate.annotations.ColumnDefault;  

import java.io.Serializable;  
import java.util.Date;  

@Data  
@Entity  
@Table(name="catalog")  
public class CatalogEntity implements Serializable {  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private long id;  
    @Column(nullable = false, length = 120, unique = true)  
    private String productId;  
    @Column(nullable = false)  
    private String productName;  
    @Column(nullable = false)  
    private Integer stock;  
    @Column(nullable = false)  
    private Integer unitPrice;  

    @Column(nullable = false, updatable = false, insertable = false)  
    @ColumnDefault( value="CURRENT_TIMESTAMP" )  
    private Date createdAt;  
}
  • 데이터베이스의 catalog 테이블을 매핑하는 엔티티 클래스
  • 주요 필드
    • id: Primary Key
    • productId, productName: 상품 ID 및 이름
    • stock, unitPrice: 재고 및 단가
    • createdAt: 생성 시간 (기본값: CURRENT_TIMESTAMP)

CatalogRepository

package com.example.CatalogService.jpa;  

import org.springframework.data.repository.CrudRepository;  

public interface CatalogRepository extends CrudRepository<CatalogEntity, Long> {  
    CatalogEntity findByProductId(String productId);  
}
  • 기능: 데이터베이스 연동
  • 주요 메서드
    • findAll(): 모든 상품 조회
    • findByProductId(String productId): 특정 상품 조회

Service 추가

  • 비즈니스 로직 추가

CatalogService

package com.example.CatalogService.service;  

import com.example.CatalogService.jpa.CatalogEntity;  

public interface CatalogService {  
    Iterable<CatalogEntity> getAllCatalogs(); 
}

CatalogServiceImpl

package com.example.CatalogService.service;  

import com.example.CatalogService.jpa.CatalogEntity;  
import com.example.CatalogService.jpa.CatalogRepository;  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.core.env.Environment;  
import org.springframework.stereotype.Service;  

@Service  
@Slf4j  
public class CatalogServiceImpl implements CatalogService{  
    private CatalogRepository repository;  
    private Environment env;  

    public CatalogServiceImpl(CatalogRepository repository, Environment env){  
        this.repository = repository;  
        this.env = env;  
    }  

    /**  
     * 상품 목록 전체 조회  
     * @return  
     */  
    @Override  
    public Iterable<CatalogEntity> getAllCatalogs() {  
        return repository.findAll();  
    }  
}
  • 기능: 비즈니스 로직 처리
  • 주요 메서드:
    • getAllCatalogs(): 전체 상품 목록 조회

Dto 추가

  • 상품 정보를 담은 객체

CatalogDto

package com.example.CatalogService.dto;  

import lombok.Data;  

import java.io.Serializable;  

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

    private String orderId;  
    private String userId;  
}

ResponseCatalog

package com.example.CatalogService.dto;  

import com.fasterxml.jackson.annotation.JsonInclude;  
import lombok.Data;  

import java.util.Date;  

@Data  
@JsonInclude(JsonInclude.Include.NON_NULL)  
public class ResponseCatalog {  
    private String productId;  
    private String productName;  
    private Integer stock;  
    private Integer unitPrice;  
    private Date createdAt;  
}

Controller 추가

  • View에서 요청한 정보를 서버에서 받아 Service를 호출한다.CatalogController
package com.example.CatalogService.controller;  

import com.example.CatalogService.dto.ResponseCatalog;  
import com.example.CatalogService.jpa.CatalogEntity;  
import com.example.CatalogService.service.CatalogService;  
import jakarta.servlet.http.HttpServletRequest;  
import org.modelmapper.ModelMapper;  
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.RequestMapping;  
import org.springframework.web.bind.annotation.RestController;  

import java.util.ArrayList;  
import java.util.List;  

@RestController  
@RequestMapping("/catalogService")  
public class CatalogController {  
    private Environment env;  
    private CatalogService catalogService;  

    @Autowired  
    public CatalogController(Environment env, CatalogService catalogService){  
        this.env = env;  
        this.catalogService = catalogService;  
    }  

    @GetMapping("/health_check")  
    public String status(HttpServletRequest request){  
        return String.format("It's Working in Catalog Service on Port %s", request.getServerPort());  
    }  

    /**  
     * 상품 목록 전체 조회  
     * @return  
     */  
    @GetMapping(value="catalogs")  
    public ResponseEntity<List<ResponseCatalog>> getCatalogs() {  
        Iterable<CatalogEntity> catalogList = catalogService.getAllCatalogs();  

        List<ResponseCatalog> result = new ArrayList<>();  
        catalogList.forEach(v -> {  
            result.add(new ModelMapper().map(v, ResponseCatalog.class));  
        });  

        return ResponseEntity.status(HttpStatus.OK).body(result);  
    }  
}
  • 역할: HTTP 요청을 처리하고 응답 반환
  • 주요 엔드포인트
    • /health_check: 애플리케이션 상태 확인
    • /catalogs: 전체 상품 목록 조회 (JSON 응답)

데이터 등록

insert into catalog(product_id, product_name, stock, unit_price) values('CATALOG-1', 'Seoul', 100, 1000);

insert into catalog(product_id, product_name, stock, unit_price) values('CATALOG-2', 'Tokyo', 100, 1200);

insert into catalog(product_id, product_name, stock, unit_price) values('CATALOG-3', 'Newyork', 100, 1500);
  • 마리아 DB 사용하여 데이터 insert

결과

요청

GET http://localhost:{PORT}/catalogService/catalogs

응답

[
    {
        "productId":"CATALOG1",
        "productName":"Seoul",
        "stock":100,
        "unitPrice":1000,
        "createdAt":"2024-06-22T12:49:30.835+00:00"
    },
    {
        "productId":"CATALOG-2",
        "productName":"Tokyo",
        "stock":100,
        "unitPrice":1200,
        "createdAt":"2024-06-22T12:49:40.080+00:00"
    },
    {
        "productId":"CATALOG-3",
        "productName":"Newyork",
        "stock":100,
        "unitPrice":1500,
        "createdAt":"2024-06-22T12:49:41.316+00:00"
    }
]
반응형