In this guide, we'll walk through the creation of a simple yet comprehensive microservices system using Spring Boot. We will cover the basics of microservices, setting up the required environment, and implementing two microservices: OrderService and InventoryService. Additionally, we'll integrate service discovery using Eureka and an API Gateway to manage routing between the services.
Microservices are a software architecture style where an application is built as a collection of small, independent services that work together. Each service is self-contained and communicates with others through well-defined APIs, making the system more flexible, scalable, and easier to manage.
The architecture of our system will consist of two microservices: OrderService and InventoryService. The OrderService will use a relational database (MySQL) to store order details, while the InventoryService will use a NoSQL database (MongoDB) for managing inventory data. We'll also implement service discovery with Eureka and use an API Gateway for routing requests.
Before we begin, ensure you have the following tools installed:
Open the application.properties file in src/main/resources and add the following configuration:
spring.datasource.url=jdbc:mysql://localhost:3306/orderservice spring.datasource.username=root spring.datasource.password=yourpassword spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect server.port=8081
Create the Order entity class in src/main/java/com/ordersystem/orderservice/model/Order.java:
package com.ordersystem.orderservice.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; @Data @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "orders") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String product; private int quantity; private double price; }
Create the OrderRepository interface in src/main/java/com/ordersystem/orderservice/repository/OrderRepository.java:
package com.ordersystem.orderservice.repository; import com.ordersystem.orderservice.model.Order; import org.springframework.data.jpa.repository.JpaRepository; public interface OrderRepository extends JpaRepository<Order, Long> { }
Create the OrderService class in src/main/java/com/ordersystem/orderservice/service/OrderService.java:
package com.ordersystem.orderservice.service; import com.ordersystem.orderservice.model.Order; import com.ordersystem.orderservice.repository.OrderRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class OrderService { @Autowired private OrderRepository orderRepository; public List<Order> getAllOrders() { return orderRepository.findAll(); } public Order getOrderById(Long id) { return orderRepository.findById(id).orElse(null); } public Order createOrder(Order order) { return orderRepository.save(order); } public void deleteOrder(Long id) { orderRepository.deleteById(id); } }
Create the OrderController class in src/main/java/com/ordersystem/orderservice/controller/OrderController.java:
package com.ordersystem.orderservice.controller; import com.ordersystem.orderservice.model.Order; import com.ordersystem.orderservice.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/orders") public class OrderController { @Autowired private OrderService orderService; @GetMapping public List<Order> getAllOrders() { return orderService.getAllOrders(); } @GetMapping("/{id}") public Order getOrderById(@PathVariable Long id) { return orderService.getOrderById(id); } @PostMapping public Order createOrder(@RequestBody Order order) { return orderService.createOrder(order); } @DeleteMapping("/{id}") public void deleteOrder(@PathVariable Long id) { orderService.deleteOrder(id); } }
Open the application.properties file in src/main/resources and add the following configuration:
spring.data.mongodb.uri=mongodb://localhost:27017/inventoryservice server.port=8082
Create the InventoryItem entity class in src/main/java/com/ordersystem/inventoryservice/model/InventoryItem.java:
package com.ordersystem.inventoryservice.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Data @AllArgsConstructor @NoArgsConstructor @Document(collection = "inventory") public class InventoryItem { @Id private String id; private String product; private int quantity; }
Create the InventoryRepository interface in src/main/java/com/ordersystem/inventoryservice/repository/InventoryRepository.java:
package com.ordersystem.inventoryservice.repository; import com.ordersystem.inventoryservice.model.InventoryItem; import org.springframework.data.mongodb.repository.MongoRepository; public interface InventoryRepository extends MongoRepository<InventoryItem, String> { }
Create the InventoryService class in src/main/java/com/ordersystem/inventoryservice/service/InventoryService.java:
package com.ordersystem.inventoryservice.service; import com.ordersystem.inventoryservice.model.InventoryItem; import com.ordersystem.inventoryservice.repository.InventoryRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class InventoryService { @Autowired private InventoryRepository inventoryRepository; public List<InventoryItem> getAllItems() { return inventoryRepository.findAll(); } public InventoryItem getItemById(String id) { return inventoryRepository.findById(id).orElse(null); } public InventoryItem createItem(InventoryItem item) { return inventoryRepository.save(item); } public void deleteItem(String id) { inventoryRepository.deleteById(id); } }
Create the InventoryController class in src/main/java/com/ordersystem/inventoryservice/controller/InventoryController.java:
package com.ordersystem.inventoryservice.controller; import com.ordersystem.inventoryservice.model.InventoryItem; import com.ordersystem.inventoryservice.service.InventoryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/inventory") public class InventoryController { @Autowired private InventoryService inventoryService; @GetMapping public List<InventoryItem> getAllItems() { return inventoryService.getAllItems(); } @GetMapping("/{id}") public InventoryItem getItemById(@PathVariable String id) { return inventoryService.getItemById(id); } @PostMapping public InventoryItem createItem(@RequestBody InventoryItem item) { return inventoryService.createItem(item); } @DeleteMapping("/{id}") public void deleteItem(@PathVariable String id) { inventoryService.delete Item(id); } }
Open the application.properties file in src/main/resources and add the following configuration:
server.port=8761 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false
Annotate the main application class in src/main/java/com/ordersystem/eurekaserver/EurekaServerApplication.java with @EnableEurekaServer:
package com.ordersystem.eurekaserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
Add the Eureka client dependency to both OrderService and InventoryService:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
Add Eureka client configuration to the application.properties files:
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ spring.application.name=order-service
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ spring.application.name=inventory-service
Open the application.yml file in src/main/resources and add the following configuration:
server: port: 8080 spring: application: name: api-gateway cloud: gateway: routes: - id: order-service uri: lb://order-service predicates: - Path=/api/orders/** - id: inventory-service uri: lb://inventory-service predicates: - Path=/api/inventory/** eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
Annotate the main application class in src/main/java/com/ordersystem/apigateway/ApiGatewayApplication.java with @EnableDiscoveryClient:
package com.ordersystem.apigateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ApiGatewayApplication { public static void main(String[] args) { SpringApplication.run(ApiGatewayApplication.class, args); } }
Use Postman or any other API client to test the endpoints through the API Gateway:
In this guide, we've built a simple microservices system using Spring Boot. We created two microservices (OrderService and InventoryService), integrated service discovery with Eureka, and set up an API Gateway for routing requests. This architecture allows for scalable and maintainable microservices that can be easily extended in the future.
The above is the detailed content of Building Your First Microservice System with Spring Boot: A Beginners Guide. For more information, please follow other related articles on the PHP Chinese website!