diff --git a/.coderabbit.yml b/.coderabbit.yml new file mode 100644 index 0000000..8511537 --- /dev/null +++ b/.coderabbit.yml @@ -0,0 +1,35 @@ +language: "ko" +early_access: false +reviews: + profile: "chill" + request_changes_workflow: false + high_level_summary: true + poem: true + review_status: true + collapse_walkthrough: false + auto_review: + enabled: true + drafts: false + path_filters: + - "!**/*.md" + - "!**/docs/**" + - "!**/.github/**" + path_instructions: + - path: "**/*.java" + instructions: | + Review this Java code for: + 1. Spring Boot best practices + 2. Clean code principles + 3. Performance optimizations + 4. Security considerations + 5. Suggest more elegant solutions using Java features + 6. Check for proper exception handling + 7. Suggest better naming conventions + - path: "**/build.gradle" + instructions: | + Review Gradle configuration for: + 1. Dependency management best practices + 2. Build optimization opportunities + 3. Plugin usage efficiency +chat: + auto_reply: true \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/MSA-SpringCloud-Kubernetes.iml b/.idea/MSA-SpringCloud-Kubernetes.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/MSA-SpringCloud-Kubernetes.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/git_toolbox_blame.xml b/.idea/git_toolbox_blame.xml new file mode 100644 index 0000000..7dc1249 --- /dev/null +++ b/.idea/git_toolbox_blame.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e9710cf --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..02f263b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/api-gateway/build.gradle b/api-gateway/build.gradle new file mode 100644 index 0000000..93e1aff --- /dev/null +++ b/api-gateway/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'org.springframework.boot' version '3.1.5' +} + +dependencies { + implementation 'org.springframework.cloud:spring-cloud-starter-gateway' + implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' +} \ No newline at end of file diff --git a/api-gateway/src/main/java/com/example/gateway/ApiGatewayApplication.java b/api-gateway/src/main/java/com/example/gateway/ApiGatewayApplication.java new file mode 100644 index 0000000..bdafec0 --- /dev/null +++ b/api-gateway/src/main/java/com/example/gateway/ApiGatewayApplication.java @@ -0,0 +1,15 @@ +package com.example.gateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +@SpringBootApplication +@EnableEurekaClient +public class ApiGatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(ApiGatewayApplication.class, args); + } + +} \ No newline at end of file diff --git a/api-gateway/src/main/resources/application.yml b/api-gateway/src/main/resources/application.yml new file mode 100644 index 0000000..e6a1c81 --- /dev/null +++ b/api-gateway/src/main/resources/application.yml @@ -0,0 +1,32 @@ +spring: + application: + name: api-gateway + cloud: + gateway: + routes: + - id: user-service + uri: lb://user-service + predicates: + - Path=/api/users/** + - id: order-service + uri: lb://order-service + predicates: + - Path=/api/orders/** + discovery: + locator: + enabled: true + lower-case-service-id: true + +server: + port: 8080 + +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka/ + instance: + prefer-ip-address: true + +logging: + level: + org.springframework.cloud.gateway: DEBUG \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..08db31f --- /dev/null +++ b/build.gradle @@ -0,0 +1,48 @@ +plugins { + id 'java' +} + +allprojects { + group = 'com.example' + version = '0.0.1-SNAPSHOT' + + repositories { + mavenCentral() + } +} + +subprojects { + apply plugin: 'java' + apply plugin: 'io.spring.dependency-management' + + java { + sourceCompatibility = '17' + } + + configurations { + compileOnly { + extendsFrom annotationProcessor + } + } + + ext { + set('springCloudVersion', "2022.0.4") + } + + // 공통 의존성 + dependencies { + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + } + + dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } + } + + tasks.named('test') { + useJUnitPlatform() + } +} \ No newline at end of file diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..9e8fb62 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,3 @@ +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' +} \ No newline at end of file diff --git a/common/src/main/java/com/example/common/BaseEntity.java b/common/src/main/java/com/example/common/BaseEntity.java new file mode 100644 index 0000000..5a55ff1 --- /dev/null +++ b/common/src/main/java/com/example/common/BaseEntity.java @@ -0,0 +1,33 @@ +package com.example.common; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; +import java.time.LocalDateTime; + +@MappedSuperclass +@Getter +@Setter +public abstract class BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, updatable = false) + private LocalDateTime createdAt; + + @Column(nullable = false) + private LocalDateTime updatedAt; + + @PrePersist + protected void onCreate() { + createdAt = LocalDateTime.now(); + updatedAt = LocalDateTime.now(); + } + + @PreUpdate + protected void onUpdate() { + updatedAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/docs/QNA.md b/docs/QNA.md new file mode 100644 index 0000000..9754287 --- /dev/null +++ b/docs/QNA.md @@ -0,0 +1,116 @@ +# 🤔 개발 과정에서의 질문과 답변 + +## MSA 아키텍처 관련 + +### Q: Spring Cloud 없이도 MSA가 가능한데 왜 사용하나요? + +**A:** Spring Cloud를 사용하는 이유는 다음과 같습니다: + +1. **서비스 디스커버리 자동화** + ```java + // Spring Cloud 없으면 + RestTemplate.getForObject("http://user-service-1:8081/api/users/1", User.class); // 하드코딩 + + // Spring Cloud 있으면 + RestTemplate.getForObject("http://user-service/api/users/1", User.class); // 자동 발견 + ``` + +2. **로드밸런싱 자동화** + - 인스턴스 장애 시 자동 전환 + - 인스턴스 추가/제거 시 자동 감지 + +3. **개발 편의성** + ```java + @FeignClient(name = "user-service") // 간단한 서비스 간 통신 + interface UserClient { + @GetMapping("/api/users/{id}") + User getUser(@PathVariable Long id); + } + ``` + +**결론**: 작은 MSA는 Spring Cloud 없어도 되지만, 서비스가 많아질수록 Spring Cloud의 자동화 기능이 큰 도움이 됩니다. + +--- + +## Gradle 멀티모듈 관련 + +### Q: 멀티모듈에서 공통 설정은 어떻게 관리하나요? + +**A:** `subprojects` 블록을 활용해서 공통 설정을 자동 적용합니다: + +```groovy +subprojects { + // 모든 하위 모듈에 자동 적용 + dependencies { + compileOnly 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + } +} +``` + +**장점**: +- 중복 설정 제거 +- 새 서비스 추가 시 최소한의 설정만 필요 +- 일관된 의존성 관리 + +### Q: 모든 서비스에서 공통 모듈을 꼭 사용해야 하나요? + +**A:** 아닙니다! 필요한 모듈만 의존성을 추가하면 됩니다: + +- **user-service**: `implementation project(':common')` ✅ (BaseEntity 사용) +- **order-service**: `implementation project(':common')` ✅ (BaseEntity 사용) +- **api-gateway**: 의존성 없음 ✅ (BaseEntity 안 씀) + +**원칙**: 필요한 모듈만 의존성 추가, 불필요한 의존성은 추가하지 않음 + +--- + +## FeignClient vs RestTemplate + +### Q: FeignClient를 왜 사용하나요? RestTemplate과 차이는? + +**A:** 둘 다 MSA에서 서비스 간 통신에 사용되지만 편의성에 차이가 있습니다: + +**RestTemplate (번거로움)**: +```java +val response = restTemplate.getForObject("http://user-service/api/users/$id", UserDto::class.java) +``` + +**FeignClient (간편함)**: +```java +@FeignClient(name = "user-service") +interface UserClient { + @GetMapping("/api/users/{id}") + UserDto getUserById(@PathVariable Long id); +} + +// 사용 +val user = userClient.getUserById(id) +``` + +**결론**: RestTemplate도 가능하지만 FeignClient가 더 선언적이고 간편합니다. + +--- + +## 기술 선택 이유 + +### Q: Maven 대신 Gradle을 선택한 이유는? + +**A:** +- **빌드 속도**: Gradle이 더 빠름 +- **문법**: Groovy 문법이 XML보다 간결 +- **현대적**: 요즘 Spring 프로젝트에서 더 많이 사용 +- **유연성**: 복잡한 빌드 로직 구현 시 더 유연 + +### Q: Java 대신 Kotlin을 처음에 시도한 이유는? + +**A:** Kotlin의 장점을 경험해보고 싶어서였지만, Java와 비교 학습을 위해 Java로 변경했습니다: + +**Kotlin 장점**: +- data class로 boilerplate 코드 최소화 +- null safety +- 간결한 문법 + +**Java를 최종 선택한 이유**: +- 두 언어의 차이점을 명확히 비교하기 위함 +- Lombok 적용 전후 비교 가능 \ No newline at end of file diff --git a/order-service/build.gradle b/order-service/build.gradle new file mode 100644 index 0000000..11f7929 --- /dev/null +++ b/order-service/build.gradle @@ -0,0 +1,14 @@ +plugins { + id 'org.springframework.boot' version '3.1.5' +} + +dependencies { + implementation project(':common') + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' + implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' + + runtimeOnly 'com.h2database:h2' +} \ No newline at end of file diff --git a/order-service/src/main/java/com/example/order/OrderServiceApplication.java b/order-service/src/main/java/com/example/order/OrderServiceApplication.java new file mode 100644 index 0000000..040972b --- /dev/null +++ b/order-service/src/main/java/com/example/order/OrderServiceApplication.java @@ -0,0 +1,17 @@ +package com.example.order; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableEurekaClient +@EnableFeignClients +public class OrderServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(OrderServiceApplication.class, args); + } + +} \ No newline at end of file diff --git a/order-service/src/main/java/com/example/order/controller/OrderController.java b/order-service/src/main/java/com/example/order/controller/OrderController.java new file mode 100644 index 0000000..f328661 --- /dev/null +++ b/order-service/src/main/java/com/example/order/controller/OrderController.java @@ -0,0 +1,36 @@ +package com.example.order.controller; + +import com.example.order.entity.Order; +import com.example.order.service.OrderService; +import com.example.order.service.OrderService.CreateOrderRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import java.util.List; + +@RestController +@RequestMapping("/api/orders") +@RequiredArgsConstructor +public class OrderController { + + private final OrderService orderService; + + @PostMapping + public ResponseEntity createOrder(@RequestBody CreateOrderRequest request) { + Order order = orderService.createOrder(request); + return ResponseEntity.status(HttpStatus.CREATED).body(order); + } + + @GetMapping + public ResponseEntity> getAllOrders() { + List orders = orderService.getAllOrders(); + return ResponseEntity.ok(orders); + } + + @GetMapping("/user/{userId}") + public ResponseEntity> getOrdersByUserId(@PathVariable Long userId) { + List orders = orderService.getOrdersByUserId(userId); + return ResponseEntity.ok(orders); + } +} \ No newline at end of file diff --git a/order-service/src/main/java/com/example/order/entity/Order.java b/order-service/src/main/java/com/example/order/entity/Order.java new file mode 100644 index 0000000..c923477 --- /dev/null +++ b/order-service/src/main/java/com/example/order/entity/Order.java @@ -0,0 +1,42 @@ +package com.example.order.entity; + +import com.example.common.BaseEntity; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import java.math.BigDecimal; + +@Entity +@Table(name = "orders") +@Getter +@Setter +@NoArgsConstructor +public class Order extends BaseEntity { + + @Column(nullable = false) + private Long userId; + + @Column(nullable = false) + private String productName; + + @Column(nullable = false) + private Integer quantity; + + @Column(nullable = false, precision = 10, scale = 2) + private BigDecimal price; + + @Enumerated(EnumType.STRING) + private OrderStatus status = OrderStatus.PENDING; + + public Order(Long userId, String productName, Integer quantity, BigDecimal price) { + this.userId = userId; + this.productName = productName; + this.quantity = quantity; + this.price = price; + } +} + +enum OrderStatus { + PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED +} \ No newline at end of file diff --git a/order-service/src/main/java/com/example/order/repository/OrderRepository.java b/order-service/src/main/java/com/example/order/repository/OrderRepository.java new file mode 100644 index 0000000..9efc4f6 --- /dev/null +++ b/order-service/src/main/java/com/example/order/repository/OrderRepository.java @@ -0,0 +1,11 @@ +package com.example.order.repository; + +import com.example.order.entity.Order; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import java.util.List; + +@Repository +public interface OrderRepository extends JpaRepository { + List findByUserId(Long userId); +} \ No newline at end of file diff --git a/order-service/src/main/java/com/example/order/service/OrderService.java b/order-service/src/main/java/com/example/order/service/OrderService.java new file mode 100644 index 0000000..7e3dc52 --- /dev/null +++ b/order-service/src/main/java/com/example/order/service/OrderService.java @@ -0,0 +1,53 @@ +package com.example.order.service; + +import com.example.order.entity.Order; +import com.example.order.repository.OrderRepository; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class OrderService { + + private final OrderRepository orderRepository; + + public Order createOrder(CreateOrderRequest request) { + Order order = new Order( + request.getUserId(), + request.getProductName(), + request.getQuantity(), + request.getPrice() + ); + return orderRepository.save(order); + } + + public List getAllOrders() { + return orderRepository.findAll(); + } + + public List getOrdersByUserId(Long userId) { + return orderRepository.findByUserId(userId); + } + + @Getter + @Setter + @NoArgsConstructor + public static class CreateOrderRequest { + private Long userId; + private String productName; + private Integer quantity; + private BigDecimal price; + + public CreateOrderRequest(Long userId, String productName, Integer quantity, BigDecimal price) { + this.userId = userId; + this.productName = productName; + this.quantity = quantity; + this.price = price; + } + } +} \ No newline at end of file diff --git a/order-service/src/main/resources/application.yml b/order-service/src/main/resources/application.yml new file mode 100644 index 0000000..750cfd3 --- /dev/null +++ b/order-service/src/main/resources/application.yml @@ -0,0 +1,29 @@ +spring: + application: + name: order-service + + datasource: + url: jdbc:h2:mem:orderdb + driverClassName: org.h2.Driver + username: sa + password: + + h2: + console: + enabled: true + path: /h2-console + + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true + +server: + port: 8082 + +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka/ + instance: + prefer-ip-address: true \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..d3006fd --- /dev/null +++ b/settings.gradle @@ -0,0 +1,6 @@ +rootProject.name = 'msa-spring-cloud-kubernetes' + +include 'common' +include 'user-service' +include 'order-service' +include 'api-gateway' \ No newline at end of file diff --git a/user-service/build.gradle b/user-service/build.gradle new file mode 100644 index 0000000..ca33c0b --- /dev/null +++ b/user-service/build.gradle @@ -0,0 +1,13 @@ +plugins { + id 'org.springframework.boot' version '3.1.5' +} + +dependencies { + implementation project(':common') + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' + + runtimeOnly 'com.h2database:h2' +} \ No newline at end of file diff --git a/user-service/src/main/java/com/example/user/UserServiceApplication.java b/user-service/src/main/java/com/example/user/UserServiceApplication.java new file mode 100644 index 0000000..a7eb5b2 --- /dev/null +++ b/user-service/src/main/java/com/example/user/UserServiceApplication.java @@ -0,0 +1,15 @@ +package com.example.user; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +@SpringBootApplication +@EnableEurekaClient +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} \ No newline at end of file diff --git a/user-service/src/main/java/com/example/user/controller/UserController.java b/user-service/src/main/java/com/example/user/controller/UserController.java new file mode 100644 index 0000000..7bfbee6 --- /dev/null +++ b/user-service/src/main/java/com/example/user/controller/UserController.java @@ -0,0 +1,44 @@ +package com.example.user.controller; + +import com.example.user.entity.User; +import com.example.user.service.UserService; +import com.example.user.service.UserService.CreateUserRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/api/users") +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + + @PostMapping + public ResponseEntity createUser(@RequestBody CreateUserRequest request) { + User user = userService.createUser(request); + return ResponseEntity.status(HttpStatus.CREATED).body(user); + } + + @GetMapping + public ResponseEntity> getAllUsers() { + List users = userService.getAllUsers(); + return ResponseEntity.ok(users); + } + + @GetMapping("/{id}") + public ResponseEntity getUserById(@PathVariable Long id) { + User user = userService.getUserById(id); + return ResponseEntity.ok(user); + } + + @GetMapping("/email/{email}") + public ResponseEntity> getUserByEmail(@PathVariable String email) { + Optional user = userService.getUserByEmail(email); + return ResponseEntity.ok(user); + } +} \ No newline at end of file diff --git a/user-service/src/main/java/com/example/user/entity/User.java b/user-service/src/main/java/com/example/user/entity/User.java new file mode 100644 index 0000000..4b03169 --- /dev/null +++ b/user-service/src/main/java/com/example/user/entity/User.java @@ -0,0 +1,27 @@ +package com.example.user.entity; + +import com.example.common.BaseEntity; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "users") +@Getter +@Setter +@NoArgsConstructor +public class User extends BaseEntity { + + @Column(nullable = false, unique = true) + private String email; + + @Column(nullable = false) + private String name; + + // 필요한 생성자만 직접 정의 + public User(String email, String name) { + this.email = email; + this.name = name; + } +} \ No newline at end of file diff --git a/user-service/src/main/java/com/example/user/repository/UserRepository.java b/user-service/src/main/java/com/example/user/repository/UserRepository.java new file mode 100644 index 0000000..663c20d --- /dev/null +++ b/user-service/src/main/java/com/example/user/repository/UserRepository.java @@ -0,0 +1,12 @@ +package com.example.user.repository; + +import com.example.user.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface UserRepository extends JpaRepository { + Optional findByEmail(String email); +} \ No newline at end of file diff --git a/user-service/src/main/java/com/example/user/service/UserService.java b/user-service/src/main/java/com/example/user/service/UserService.java new file mode 100644 index 0000000..747ab4c --- /dev/null +++ b/user-service/src/main/java/com/example/user/service/UserService.java @@ -0,0 +1,50 @@ +package com.example.user.service; + +import com.example.user.entity.User; +import com.example.user.repository.UserRepository; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class UserService { + + private final UserRepository userRepository; + + public User createUser(CreateUserRequest request) { + User user = new User(request.getEmail(), request.getName()); + return userRepository.save(user); + } + + public List getAllUsers() { + return userRepository.findAll(); + } + + public User getUserById(Long id) { + return userRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("User not found with id: " + id)); + } + + public Optional getUserByEmail(String email) { + return userRepository.findByEmail(email); + } + + @Getter + @Setter + @NoArgsConstructor + public static class CreateUserRequest { + private String email; + private String name; + + public CreateUserRequest(String email, String name) { + this.email = email; + this.name = name; + } + } +} \ No newline at end of file diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml new file mode 100644 index 0000000..4f35a5c --- /dev/null +++ b/user-service/src/main/resources/application.yml @@ -0,0 +1,36 @@ +spring: + application: + name: user-service + + datasource: + url: jdbc:h2:mem:userdb + driverClassName: org.h2.Driver + username: sa + password: + + h2: + console: + enabled: true + path: /h2-console + + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true + properties: + hibernate: + format_sql: true + +server: + port: 8081 + +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka/ + instance: + prefer-ip-address: true + +logging: + level: + com.example: DEBUG \ No newline at end of file