티스토리 뷰

Eureka 서버와 JPA로 아주 간단한 쇼핑몰 BackEnd 소스를 작성하였습니다. SpringBoot로 구현하였으며, MariaDB를 사용하였습니다.


1. 테이블 생성

CREATE TABLE `products` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  `price` double NOT NULL,
  `stock` double NOT NULL,
  `created_at` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `created_at` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `orders` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `product_id` bigint(20) NOT NULL,
  `total` double NOT NULL,
  `created_at` timestamp NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`)
);
  • products : 상품정보를 담을 테이블
  • users : 사용자 정보를 담을 테이블
  • orders : 주문 정보를 담을 테이블



2. 데이터 입력

  • users와 products 테이블에 테스트 데이터를 입력합니다.
INSERT INTO mymall.users (username,password,email)
VALUES ('차영빈','1234','zero-bin@navercom');

INSERT INTO mymall.products (name,description,price,stock)
VALUES ('모니터','24인치 모니터입니다',50000,1);



3. 소스작성

  • SpringBoot 프로젝트를 총 4개 생성합니다. 자세한 소스는 Github를 참고해 주세요. 실행순서는 "유레카서버 > 사용자 서비스" > "상품 서비스" > "주문 서비스" 순으로 실행시키시면 됩니다.
    • EurekaServer : 유레카 서버
    • UserService : 사용자 서비스
    • ProductService : 상품 서비스
    • OrderService : 주문 서비스

 

3.1. Eureka Server

3.1.1. build.gradle

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

3.1.2. application.yml

server:
  port: 1220

spring:
  application:
    name: MyMallService

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

3.1.3. SpringBootApplication.java

@EnableEurekaServer
@SpringBootApplication
public class MyMallApplication {
  public static void main(String[] args) {
    SpringApplication.run(MyMallApplication.class, args);
  }
}

3.1.4. 실행 확인

설정이 완료되면 유레카 서버를 확인할 수 있습니다.



3.2. UserService

  • 사용자 서비스

3.2.1. build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.4'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

3.2.2. application.yml

server:
  port: 1221

spring:
  application:
    name: user-service

  datasource:
    url: jdbc:mariadb://localhost:3306/mymall
    username: root
    password: root

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:1220/eureka

3.2.3. SpringBootApplication.java

@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceApplication {
  public static void main(String[] args) {
    SpringApplication.run(UserServiceApplication.class, args);
  }
}

3.2.4. User.java

@Getter
@Setter
@Entity(name = "users")
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String username;
  private String password;
  private String email;
  private String created_at;
}

3.2.5. UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {
}

3.2.6. UserController.java

@RestController
@RequiredArgsConstructor
@RequestMapping("/users")
public class UserController {

  private final UserRepository _userRepository;

  @GetMapping("/{id}")
  public ResponseEntity<User> getUserById(@PathVariable Long id) {
    Optional<User> user = _userRepository.findById(id);
    return user.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
  }
}



3.3. ProductService

  • 물품 서비스

3.3.1. build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.4'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

3.3.2. application.yml

server:
  port: 1221

spring:
  application:
    name: product-service

  datasource:
    url: jdbc:mariadb://localhost:3306/mymall
    username: root
    password: root

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:1220/eureka

3.3.3. SpringBootApplication.java

@EnableDiscoveryClient
@SpringBootApplication
public class ProductServiceApplication {
  public static void main(String[] args) {
    SpringApplication.run(ProductServiceApplication.class, args);
  }
}

3.3.4. Product.java

@Getter
@Setter
@Entity(name = "products")
public class Product {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String name;
  private String description;
  private double price;
  private double stock;
  private String created_at;
}

3.3.5. ProductRepository.java

public interface ProductRepository extends JpaRepository<Product, Long> {
}

3.3.6. ProductController.java

@RestController
@RequiredArgsConstructor
@RequestMapping("/products")
public class ProductController {

  private final ProductRepository _productRepository;

  @GetMapping("/{id}")
  public ResponseEntity<Product> getProductById(@PathVariable Long id) {
    Optional<Product> product = _productRepository.findById(id);
    return product.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
  }
}



3.4. OrderService

  • 주문 서비스

3.4.1. build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.4'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

3.4.2. application.yml

server:
  port: 1223

spring:
  application:
    name: order-service

  datasource:
    url: jdbc:mariadb://localhost:3306/mymall
    username: root
    password: root

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:1220/eureka

3.4.3. SpringBootApplication.java

@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
  public static void main(String[] args) {
    SpringApplication.run(OrderServiceApplication.class, args);
  }
}

3.4.4. UserClient.java

@FeignClient(name = "user-service")
public interface UserClient {
  @GetMapping("/users/{id}")
  User getUserById(@PathVariable Long id);
}

3.4.5. ProductClient.java

@FeignClient(name = "product-service")
public interface ProductClient {
  @GetMapping("/products/{id}")
  Product getProductById(@PathVariable Long id);
}

3.4.6. User.java

@Getter
@Setter
public class User {
  private Long id;
  private String username;
  private String password;
  private String email;
  private String created_at;
}

3.4.7. Product.java

@Getter
@Setter
public class Product {
  private Long id;
  private String name;
  private String description;
  private double price;
  private double stock;
  private String created_at;
}

3.4.8. Order.java

@Getter
@Setter
@Entity(name = "orders")
public class Order {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private Long user_id;
  private Long product_id;
  private double total;
  private String created_at;
}

3.4.9. OrderRepository.java

public interface OrderRepository extends JpaRepository<Order, Long> {
}

3.4.10. OrderController.java

@RestController
@RequiredArgsConstructor
@RequestMapping("/orders")
public class OrderController {

  private final OrderRepository _orderRepository;
  private final UserClient _userClient;
  private final ProductClient _productClient;

  @PostMapping
  public ResponseEntity<Order> createOrder(@RequestBody Order order) {
    User user = _userClient.getUserById(order.getUser_id());
    if (user == null) {
      return ResponseEntity.badRequest().build();
    }

    Product product = _productClient.getProductById(order.getProduct_id());
    if (product == null) {
      return ResponseEntity.badRequest().build();
    }

    Order savedOrder = _orderRepository.save(order);
    return ResponseEntity.ok(savedOrder);
  }

}



4. 호출

  • UserService 직접 호출(GET) : http://127.0.0.1:1221/users/1
  • ProductSerivce 직접 호출(GET) : http://127.0.0.1:1222/products/1
  • OrderService 호출(POST) : http://127.0.0.1:1223/orders

 

감사합니다.

 
최근에 올라온 글
Total
Today
Yesterday