Introduction
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.
What is a Microservice?
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.
System Architecture
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.
Project Setup
Before we begin, ensure you have the following tools installed:
- IDE: IntelliJ IDEA (preferred) or Eclipse
- JDK: Version 17 or later
- Build Tool: Maven
- Databases: MySQL and MongoDB
Microservice 1: Order Service
Step 1: Initialize the Project
- Go to Spring Initializr.
- Fill in the project details:
- Project: Maven Project
- Language: Java
- Spring Boot: 2.5.7 (or a compatible version)
-
Group:
com.ordersystem
-
Artifact:
order-service
-
Name:
order-service
-
Package name:
com.ordersystem.orderservice
- Packaging: Jar
- Java: 17
- Add the following dependencies:
- Spring Web
- Spring Data JPA
- MySQL Driver
- Lombok
- Click Generate to download the project. Extract the downloaded zip file and open it in your IDE.
Step 2: Configure the Application
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
Step 3: Implement the Model
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;
}
Step 4: Create the Repository
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> {
}
Step 5: Implement the Service
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);
}
}
Step 6: Create the Controller
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);
}
}
Microservice 2: Inventory Service
Step 1: Initialize the Project
- Go to Spring Initializr.
- Fill in the project details:
- Project: Maven Project
- Language: Java
- Spring Boot: 2.5.7 (or a compatible version)
-
Group:
com.ordersystem
-
Artifact:
inventory-service
-
Name:
inventory-service
-
Package name:
com.ordersystem.inventoryservice
- Packaging: Jar
- Java: 17
- Add the following dependencies:
- Spring Web
- Spring Data MongoDB
- Lombok
- Click Generate to download the project. Extract the downloaded zip file and open it in your IDE.
Step 2: Configure the Application
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
Step 3: Implement the Model
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;
}
Step 4: Create the Repository
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> {
}
Step 5: Implement the Service
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);
}
}
Step 6: Create the Controller
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);
}
}
Service Discovery with Eureka
Step 1: Initialize the Eureka Server
- Go to Spring Initializr.
- Fill in the project details:
- Project: Maven Project
- Language: Java
- Spring Boot: 2.5.7 (or a compatible version)
-
Group:
com.ordersystem
-
Artifact:
eureka-server
-
Name:
eureka-server
-
Package name:
com.ordersystem.eurekaserver
- Packaging: Jar
- Java: 17
- Add the Eureka Server dependency.
- Click Generate to download the project. Extract the downloaded zip file and open it in your IDE.
Step 2: Configure the Eureka Server
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
Step 3: Enable Eureka Server
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);
}
}
Integrate Services with Eureka
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:
Order Service:
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
spring.application.name=order-service
Inventory Service:
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
spring.application.name=inventory-service
API Gateway
Step 1: Initialize the API Gateway
- Go to Spring Initializr.
- Fill in the project details:
- Project: Maven Project
- Language: Java
- Spring Boot: 2.5.7 (or a compatible version)
-
Group:
com.ordersystem
-
Artifact:
api-gateway
-
Name:
api-gateway
-
Package name:
com.ordersystem.apigateway
- Packaging: Jar
- Java: 17
- Add the Gateway and Eureka Discovery Client dependencies.
- Click Generate to download the project. Extract the downloaded zip file and open it in your IDE.
Step 2: Configure the API Gateway
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/
Step 3: Enable Discovery Client
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);
}
}
Testing the Microservices
- Start Eureka Server: Run the Eureka Server application.
- Start Order Service: Run the Order Service application.
- Start Inventory Service: Run the Inventory Service application.
- Start API Gateway: Run the API Gateway application.
Use Postman or any other API client to test the endpoints through the API Gateway:
-
Create Order:
POST http://localhost:8080/api/orders
-
Get Orders:
GET http://localhost:8080/api/orders
-
Create Inventory Item:
POST http://localhost:8080/api/inventory
-
Get Inventory Items:
GET http://localhost:8080/api/inventory
Conclusion
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.