A robust, scalable microservices-based e-commerce platform built with Spring Boot, Spring Cloud, and modern resilience patterns. This system demonstrates enterprise-grade architecture with service discovery, API Gateway, circuit breakers, and distributed resilience patterns.
- Architecture Overview
- Microservices
- Tech Stack & Libraries
- Project Structure
- Getting Started
- Database Schema
- API Documentation
- Resilience Patterns
- Configuration
- Monitoring & Health Checks
graph TB
Client["Client Application"]
Gateway["API Gateway<br/>Port: 8080"]
subgraph "Service Mesh"
OrderSvc["Order Service<br/>Port: 8082"]
InventorySvc["Inventory Service<br/>Port: 8081"]
end
subgraph "Infrastructure"
Eureka["Eureka Discovery<br/>Port: 8761"]
ConfigSvr["Config Server<br/>Port: 8888"]
end
subgraph "Databases"
OrderDB["PostgreSQL<br/>OrderDB"]
InventoryDB["PostgreSQL<br/>InventoryDB"]
end
Client -->|Routes Requests| Gateway
Gateway -->|Service Discovery| Eureka
Gateway -->|Route to Services| OrderSvc
Gateway -->|Route to Services| InventorySvc
OrderSvc -->|Register| Eureka
InventorySvc -->|Register| Eureka
OrderSvc -->|OpenFeign Call| InventorySvc
OrderSvc -->|Persist Data| OrderDB
InventorySvc -->|Persist Data| InventoryDB
OrderSvc -->|Fetch Config| ConfigSvr
InventorySvc -->|Fetch Config| ConfigSvr
sequenceDiagram
participant Client
participant Gateway as API Gateway
participant Eureka as Service Registry
participant OrderSvc as Order Service
participant InventorySvc as Inventory Service
participant OrderDB as OrderDB
participant InventoryDB as InventoryDB
Client->>Gateway: POST /orders/api/v1/orders
Gateway->>Eureka: Lookup order-service
Eureka-->>Gateway: Service Instance
Gateway->>OrderSvc: Forward Request
OrderSvc->>OrderDB: Save Order
OrderDB-->>OrderSvc: Order Saved
OrderSvc->>InventorySvc: OpenFeign: Check Inventory
InventorySvc->>InventoryDB: Query Products
InventoryDB-->>InventorySvc: Product Data
InventorySvc-->>OrderSvc: Inventory Response
OrderSvc-->>Gateway: Order Response
Gateway-->>Client: Response
- Central entry point for all client requests
- Routes requests to appropriate microservices
- Implements global logging filters
- Authentication & authorization
- Circuit breaker integration with Resilience4j
Key Components:
GlobalLoggingFilter: Pre and post-request loggingAuthenticationFilter: JWT validationOrderController: Routes order-related requests
- Manages order creation, retrieval, and status updates
- Communicates with Inventory Service via OpenFeign
- Implements retry and circuit breaker patterns
- Database: PostgreSQL (OrderDB)
Key Entities:
OrdersEntity: Main order recordOrderItemsEntity: Individual items in an orderOrderStatus: PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED
Key Components:
OrderService: Business logicOrderController: REST endpointsInventoryOpenFeignClient: Remote call to Inventory ServiceOrderRepo: JPA Repository
- Manages product inventory and stock levels
- Validates product availability
- Updates inventory on order placement
- Database: PostgreSQL (InventoryDB)
Key Entities:
ProductEntity: Product information with stock levels
Key Components:
ProductService: Business logicProductsController: REST endpointsOrderFeignClient: Receives order data
- Service registry for dynamic service discovery
- Maintains health status of all services
- Enables client-side load balancing
- Centralized configuration management
- Supports externalized properties
- Dynamic configuration updates
| Library | Version | Purpose |
|---|---|---|
| Spring Boot | 3.4.0 | Application framework |
| Spring Cloud | 2024.0.0 | Microservices patterns |
| Java | 21 | Language |
| Gradle | 9.6.1 | Build tool |
| Library | Purpose |
|---|---|
| Spring Cloud Gateway | API routing and filtering |
| OpenFeign | Declarative HTTP client |
| Spring Cloud Netflix Eureka | Service discovery |
| Spring Cloud Config | Centralized configuration |
| Library | Purpose |
|---|---|
| Resilience4j | Circuit breaker, retry, rate limiter |
| Spring Boot Actuator | Health checks, metrics, monitoring |
| Micrometer | Metrics collection |
| Library | Purpose |
|---|---|
| Spring Data JPA | ORM and repository pattern |
| Hibernate | JPA implementation |
| PostgreSQL Driver | Database connectivity |
| H2 Database | Local development testing |
| Library | Purpose |
|---|---|
| Spring Security | Authentication & authorization |
| JWT (jjwt) | Token-based authentication |
| Library | Purpose |
|---|---|
| Lombok | Boilerplate code reduction |
| ModelMapper | Entity-DTO mapping |
| java-dotenv | Environment variable loading |
| Library | Purpose |
|---|---|
| JUnit 5 | Unit testing framework |
| Mockito | Mocking framework |
| Testcontainers | Integration testing with Docker |
| Spring Test | Spring application testing |
ecommerce/
├── api_gateway/ # API Gateway Module
│ ├── src/main/java/com/ecart/silversurfer/api_gateway/
│ │ ├── controllers/
│ │ │ └── OrderController.java
│ │ ├── filters/
│ │ │ ├── GlobalLoggingFilter.java
│ │ │ ├── AuthenticationFilter.java
│ │ │ └── LoggingOrderFilter.java
│ │ ├── services/
│ │ │ └── JwtService.java
│ │ └── ApiGatewayApplication.java
│ ├── src/main/resources/
│ │ └── application.yaml
│ ├── build.gradle
│ └── settings.gradle
│
├── order_service/ # Order Service Module
│ ├── src/main/java/com/ecart/silversurfer/order_service/
│ │ ├── controllers/
│ │ │ └── OrderController.java
│ │ ├── services/
│ │ │ └── OrderService.java
│ │ ├── repositories/
│ │ │ └── OrderRepo.java
│ │ ├── entities/
│ │ │ ├── OrdersEntity.java
│ │ │ ├── OrderItemsEntity.java
│ │ │ └── enums/OrderStatus.java
│ │ ├── dtos/
│ │ │ ├── OrderRequestDto.java
│ │ │ └── OrderRequestItemDto.java
│ │ ├── clients/
│ │ │ └── InventoryOpenFeignClient.java
│ │ ├── config/
│ │ └── OrderServiceApplication.java
│ ├── src/main/resources/
│ │ └── application.properties
│ ├── build.gradle
│ └── settings.gradle
│
├── inventory_service/ # Inventory Service Module
│ ├── src/main/java/com/ecart/silversurfer/inventory_service/
│ │ ├── controllers/
│ │ │ └── ProductsController.java
│ │ ├── services/
│ │ │ └── ProductService.java
│ │ ├── repositories/
│ │ │ └── ProductRepo.java
│ │ ├── entities/
│ │ │ └── ProductEntity.java
│ │ ├── dtos/
│ │ │ └── ProductDto.java
│ │ ├── clients/
│ │ │ └── OrderFeignClient.java
│ │ └── InventoryServiceApplication.java
│ ├── src/main/resources/
│ │ └── application.properties
│ ├── build.gradle
│ └── settings.gradle
│
├── discovery_service/ # Eureka Discovery Service
│ ├── src/main/resources/
│ │ └── application.yaml
│ └── build.gradle
│
├── config_server/ # Config Server
│ ├── src/main/resources/
│ │ └── application.yaml
│ └── build.gradle
│
├── build.gradle # Root Gradle build file
├── settings.gradle # Gradle settings
├── .env # Environment variables
└── README.md # This file
- Java 21+
- PostgreSQL 12+
- Gradle 9.6.1+
- Docker (optional, for Testcontainers)
git clone https://github.com/rahulsinghfaujdar/ECommerceMicroservice.git
cd ecommerceCreate or update .env file:
SPRING_SECURITY_USER_NAME=admin
SPRING_SECURITY_USER_PASSWORD=12345
DB_URL=jdbc:postgresql://localhost:5432/OrderDB
DB_USERNAME=postgres
DB_PASSWORD=1234# Create databases
createdb OrderDB
createdb InventoryDB./gradlew clean buildTerminal 1 - Discovery Service (Eureka)
cd discovery_service
./gradlew bootRun
# Access: http://localhost:8761Terminal 2 - Config Server
cd config_server
./gradlew bootRun
# Access: http://localhost:8888Terminal 3 - Inventory Service
cd inventory_service
./gradlew bootRun
# Access: http://localhost:8081/inventoryTerminal 4 - Order Service
cd order_service
./gradlew bootRun
# Access: http://localhost:8082/ordersTerminal 5 - API Gateway
cd api_gateway
./gradlew bootRun
# Access: http://localhost:8080CREATE TABLE orders (
order_id BIGSERIAL PRIMARY KEY,
customer_name VARCHAR(255) NOT NULL,
order_status VARCHAR(50) DEFAULT 'PENDING',
total_price DECIMAL(10, 2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE order_items (
item_id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
quantity INT NOT NULL,
price DECIMAL(10, 2),
FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE
);CREATE TABLE products (
product_id BIGSERIAL PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
quantity INT NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);POST /orders/api/v1/orders
Content-Type: application/json
Authorization: Bearer <JWT_TOKEN>
{
"customerName": "John Doe",
"items": [
{
"productId": 1,
"quantity": 2
},
{
"productId": 2,
"quantity": 1
}
]
}Response:
{
"orderId": 1,
"customerName": "John Doe",
"orderStatus": "PENDING",
"totalPrice": 299.99,
"items": [
{
"productId": 1,
"quantity": 2,
"price": 149.99
}
]
}GET /orders/api/v1/orders/{orderId}
Authorization: Bearer <JWT_TOKEN>GET /orders/api/v1/orders
Authorization: Bearer <JWT_TOKEN>GET /inventory/api/v1/products
Authorization: Bearer <JWT_TOKEN>Response:
{
"products": [
{
"productId": 1,
"productName": "Laptop",
"price": 999.99,
"quantity": 10,
"description": "High-performance laptop"
}
]
}GET /inventory/api/v1/products/{productId}
Authorization: Bearer <JWT_TOKEN>PUT /inventory/api/v1/products/{productId}
Content-Type: application/json
{
"quantity": 5,
"price": 899.99
}GET /orders/api/v1/actuator/health
GET /orders/api/v1/actuator/metricsGET /inventory/api/v1/actuator/health
GET /inventory/api/v1/actuator/metricsGET /orders/api/v1/actuator/health/circuitbreakers
GET /inventory/api/v1/actuator/health/circuitbreakersThe system implements Resilience4j Circuit Breaker to prevent cascading failures:
resilience4j:
circuitbreaker:
instances:
inventoryCircuitBreaker:
register-health-indicator: true
sliding-window-size: 3
sliding-window-type: COUNT_BASED
minimum-number-of-calls: 10
failure-rate-threshold: 50
wait-duration-in-open-state: 1s
permitted-number-of-calls-in-half-open-state: 3States:
- CLOSED: Normal operation, requests pass through
- OPEN: Service is down, requests fail immediately
- HALF_OPEN: Testing if service recovered, limited requests allowed
Automatic retry on transient failures:
resilience4j:
retry:
configs:
default:
maxRetryAttempts: 3
waitDuration: 10s
instances:
inventoryRetry:
baseConfig: default
waitDuration: 200msConfiguration:
- Max retry attempts: 3
- Initial wait duration: 10 seconds
- Retry wait duration: 200 milliseconds
Prevent service overload:
resilience4j:
ratelimiter:
instances:
inventoryRateLimiter:
limit-refresh-period: 5s
limit-for-period: 1
timeout-duration: 1msOpenFeign is used for declarative HTTP communication:
@FeignClient(name = "inventory-service",
url = "http://localhost:8081",
fallback = InventoryFeignClientFallback.class)
public interface InventoryOpenFeignClient {
@PostMapping("/inventory/api/v1/products/reserve")
InventoryResponse reserveProducts(@RequestBody OrderRequestDto request);
}# Server Configuration
spring.application.name=order-service
server.servlet.context-path=/orders
server.port=8082
# Eureka Discovery
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.prefer-ip-address=true
# Database
spring.datasource.url=jdbc:postgresql://localhost:5432/OrderDB
spring.datasource.username=postgres
spring.datasource.password=1234
spring.datasource.driver-class-name=org.postgresql.Driver
# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
# Actuator & Monitoring
management.endpoints.web.exposure.include=health,info,metrics,prometheus
management.endpoint.health.show-details=always
management.health.circuitbreakers.enabled=true
# Resilience4j Configuration
resilience4j.retry.configs.default.maxRetryAttempts=3
resilience4j.retry.configs.default.waitDuration=10s
resilience4j.circuitbreaker.instances.inventoryCircuitBreaker.register-health-indicator=trueAll services expose Spring Boot Actuator endpoints:
| Endpoint | Purpose |
|---|---|
/actuator/health |
Overall service health |
/actuator/health/circuitbreakers |
Circuit breaker status |
/actuator/health/diskSpace |
Disk space availability |
/actuator/metrics |
Prometheus metrics |
/actuator/info |
Application info |
{
"status": "UP",
"components": {
"circuitbreakers": {
"status": "UP",
"details": {
"inventoryCircuitBreaker": {
"status": "CLOSED"
}
}
},
"db": {
"status": "UP",
"details": {
"database": "PostgreSQL"
}
}
}
}Access the Eureka service registry dashboard:
http://localhost:8761
Import the provided Postman collection to test all APIs:
http://localhost:8080
All requests require a Bearer token. Use JWT authentication:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
POST /orders/api/v1/orders- Create new orderGET /orders/api/v1/orders- List all ordersGET /orders/api/v1/orders/{orderId}- Get order detailsPUT /orders/api/v1/orders/{orderId}- Update order status
GET /inventory/api/v1/products- List all productsGET /inventory/api/v1/products/{productId}- Get product detailsPUT /inventory/api/v1/products/{productId}- Update productPOST /inventory/api/v1/products/reserve- Reserve products for order
GET /orders/api/v1/actuator/health- Order service healthGET /inventory/api/v1/actuator/health- Inventory service healthGET /orders/api/v1/actuator/health/circuitbreakers- Circuit breaker status
Import Steps:
- Open Postman
- Click "Import" button
- Select the Postman collection file
- Set environment variables (base_url, token, etc.)
- Start testing!
graph LR
A["Client"] -->|Credentials| B["Auth Filter"]
B -->|Validates JWT| C["JwtService"]
C -->|Token Valid| D["Request Proceeds"]
C -->|Token Invalid| E["401 Unauthorized"]
- Header: Algorithm (HS256)
- Payload: User claims, expiry time
- Signature: HMAC-SHA256 encoded
./gradlew test./gradlew integrationTest./gradlew test --info- Verify Eureka server is running on port 8761
- Check firewall settings
- Ensure
eureka.client.service-url.defaultZoneis correct
- Verify PostgreSQL is running
- Check database credentials in properties file
- Ensure OrderDB and InventoryDB are created
- Check the actual service health
- Monitor logs for exceptions
- Adjust
waitDurationInOpenStateif needed
- Check Inventory Service is running
- Verify network connectivity
- Review retry and timeout configurations
- Spring Cloud Gateway Documentation
- Resilience4j Documentation
- Spring Cloud Netflix Eureka
- OpenFeign Documentation
- PostgreSQL Documentation
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the MIT License - see LICENSE file for details.
For issues, questions, or suggestions:
- GitHub Issues: ECommerceMicroservice Issues
- Email: rahulsinghfaujdar@example.com
Built with ❤️ using Spring Boot & Microservices Architecture