Welcome to the Synapse E-commerce Platform, a modern, reactive, and resilient microservices-based application designed to showcase a complete e-commerce workflow. This project is built entirely in Kotlin using the Spring Boot framework and leverages a suite of powerful technologies to deliver a scalable and maintainable system.
The platform follows a microservices architecture, with each service responsible for a specific business domain. Services communicate asynchronously via a message broker (Kafka) and synchronously via REST and gRPC where appropriate.
flowchart TD
subgraph Clients
direction LR
User["<div style='font-size: 1.2em; font-weight: bold; color: black;'>π€ End User</div><div style='font-size: 0.9em; color: black;'>Browser/Mobile App</div>"]
end
subgraph "Network & API Layer"
direction LR
Gateway["<div style='font-size: 1.2em; font-weight: bold; color: black;'>π API Gateway</div><div style='font-size: 0.9em; color: black;'>Spring Cloud Gateway<br/>Routing, Rate Limiting, Security</div>"]
end
subgraph "Core Business Services"
direction TB
Auth["<strong style='color: black;'>π Auth Service</strong><br/><span style='color: black;'>User Mgmt, JWT, MFA</span>"]
Product["<strong style='color: black;'>π¦ Product Service</strong><br/><span style='color: black;'>Catalog & Inventory Mgmt</span>"]
Order["<strong style='color: black;'>π Order Service</strong><br/><span style='color: black;'>Order Lifecycle & SAGA Initiator</span>"]
Payment["<strong style='color: black;'>π³ Payment Service</strong><br/><span style='color: black;'>Payment Processing & Webhooks</span>"]
end
subgraph "Data Query & Search Services"
direction TB
Search["<strong style='color: black;'>π Search Service</strong><br/><span style='color: black;'>Elasticsearch-based Queries</span>"]
end
subgraph "Service Discovery"
Registry["<strong style='color: black;'>π§ Registry Service</strong><br/><span style='color: black;'>Netflix Eureka</span>"]
end
subgraph "Event Backbone & Data Pipeline"
direction TB
Kafka["<div style='font-size: 1.2em; font-weight: bold; color: black;'>π¬ Apache Kafka</div><div style='font-size: 0.9em; color: black;'>Durable Event Bus</div>"] --- Debezium["<strong style='color: black;'>π Debezium Connect</strong><br/><span style='color: black;'>Change Data Capture</span>"]
end
subgraph "Data Persistence Layer"
direction LR
Postgres[("<span style='color: black;'>π<br/><strong>PostgreSQL</strong><br/>Auth, Orders, Payments<br/>Transactional Data & Outbox</span>")]
Mongo[("<span style='color: black;'>π<br/><strong>MongoDB</strong><br/>Product Catalog<br/>Flexible Documents & Outbox</span>")]
Elasticsearch[("<span style='color: black;'>β‘<br/><strong>Elasticsearch</strong><br/>Denormalized Search Index</span>")]
Redis[("<span style='color: black;'>π§<br/><strong>Redis (ReBloom)</strong><br/>Cache, Sessions, Cuckoo Filters</span>")]
end
subgraph "External Integrations"
direction TB
Twilio["<strong style='color: black;'>π± Twilio</strong><br/><span style='color: black;'>SMS OTP Service</span>"]
Razorpay["<strong style='color: black;'>π΅ Razorpay</strong><br/><span style='color: black;'>Payment Gateway</span>"]
end
User -->|HTTPS API Calls| Gateway
Gateway -->|Routes Traffic| Auth
Gateway -->|Routes Traffic| Product
Gateway -->|Routes Traffic| Order
Gateway -->|Routes Traffic| Search
Gateway -.-> Registry
Auth -.-> Registry
Product -.-> Registry
Order -.-> Registry
Payment -.-> Registry
Search -.-> Registry
Auth -->|"R2DBC (Writes State + Outbox)"| Postgres
Product -->|"Reactive Mongo (Writes State + Outbox)"| Mongo
Order -->|"R2DBC (Writes State + Outbox)"| Postgres
Payment -->|"R2DBC (Writes State + Outbox)"| Postgres
Postgres -->|"Tails Transaction Log"| Debezium
Mongo -->|"Tails Oplog"| Debezium
Debezium -->|"Reliably Publishes Events"| Kafka
Kafka -->|"OrderCreated Event"| Payment
Kafka -->|"PaymentProcessed Event"| Product
Kafka -->|"InventoryReserved Event"| Order
Kafka -->|"Product/Seller Events"| Search
Search -->|"Indexes Data"| Elasticsearch
Order ==>|"gRPC (Product Validation)"| Product
Gateway -->|"Rate Limiting"| Redis
Auth -->|"Cuckoo Filter & Sessions"| Redis
Product -->|"Cuckoo Filter (SKU Check)"| Redis
Auth -->|"Sends OTP"| Twilio
Payment -->|"Processes Payments"| Razorpay
style User fill:#e0b2ff,stroke:#333,stroke-width:2px
style Gateway fill:#a7c7e7,stroke:#333,stroke-width:2px
style Kafka fill:#ffdd99,stroke:#333,stroke-width:2px
style Debezium fill:#c1e1c1,stroke:#333,stroke-width:2px
classDef service fill:#d4f0f0,stroke:#003366,stroke-width:2px
classDef querySvc fill:#f0e68c,stroke:#8b4513,stroke-width:2px
classDef infra fill:#f5f5dc,stroke:#808080,stroke-width:1px,stroke-dasharray: 5 5
classDef external fill:#ffb3ba,stroke:#a52a2a,stroke-width:1px
class Auth,Product,Order,Payment service
class Search querySvc
class Registry,Twilio,Razorpay external
class Postgres,Mongo,Elasticsearch,Redis infra
This project is not just a collection of services but an implementation of modern software engineering principles.
auth, order, and product services. This ensures that an event is published if and only if the corresponding database transaction is successful.domain: Contains the core business models, logic, and ports (interfaces).application: Orchestrates the use cases by interacting with the domain.infrastructure: Contains the adapters that implement the ports and interact with external systems like databases, message brokers, and third-party APIs.search-service with Elasticsearch).| Category | Technology |
|---|---|
| Language/Framework | Kotlin 1.9+, Spring Boot 3+ (WebFlux) |
| Service Mesh | Spring Cloud (Gateway, Netflix Eureka) |
| Databases | PostgreSQL (Auth, Order, Payment), MongoDB (Product), Elasticsearch (Search) |
| Caching | Redis |
| Messaging | Apache Kafka |
| Communication | REST, gRPC (Order Service <-> Product Service) |
| Security | JWT (JSON Web Tokens), Spring Security |
| Resilience | Resilience4j (Circuit Breaker) |
| Third-Party APIs | Razorpay (Payments), Twilio (SMS OTP) |
| API Documentation | OpenAPI (Swagger) |
| Testing | JUnit 5, MockK, Testcontainers, StepVerifier |
IpKeyResolver and Redis to protect against abuse.SellerRegisteredEvent to Kafka whenever a user with a SELLER role registers.SellerRegisteredEvent from Kafka, creating a temporary seller profile that can be fully registered later.ProductCreated, BrandUpdated, CategoryDeleted) to Kafka, ensuring data consistency.order-service.product-service by consuming product-related events from Kafka and updating its Elasticsearch index accordingly.product-service before creating an order.OrderCreatedEvent to Kafka upon successful order creation, which in turn triggers the payment process in the payment-service.OrderCreatedEvent from Kafka.PaymentSuccess, PaymentFailure) back to Kafka for other services to consume.git clone https://your-repository-url.com/synapse-ecommerce.git
cd synapse-ecommerce
Environment Variables:
Each service contains an application.properties (or .yml) file. You will need to configure the following properties, ideally through environment variables or a .env file for Docker Compose.
Common:
SPRING_PROFILES_ACTIVE=dockerService-specific:
auth-service: JWT secrets, Twilio SID/Tokenpayment-service: Razorpay Key ID/Secretproduct-service: Twilio SID/TokenYou can build all services at once from the root directory.
# From the root directory of the project
./mvnw clean install
The most convenient way to run the entire platform is with Docker Compose. A docker-compose.yml file is provided at the root of the project to build and run all services and their dependencies.
.env file in the root directory and populate it with all the required configuration properties. A sample .env.example can be used as a template.docker-compose up --build -d
```3. **To check the logs for a specific service:**
```bash
docker-compose logs -f <service_name>
# e.g., docker-compose logs -f auth-service
docker-compose down
The API is exposed through the Gateway Service, which runs on port 8080.
| Method | Endpoint | Service | Description | Authorization |
|---|---|---|---|---|
POST |
/api/v1/auth/register |
auth-service |
Register a new user. | Public |
POST |
/api/v1/auth/login |
auth-service |
Log in and receive JWT tokens. | Public |
POST |
/api/v1/auth/forgot-password |
auth-service |
Initiate the password reset process. | Public |
POST |
/api/v1/products/seller/register |
product-service |
Complete seller registration details. | SELLER |
POST |
/api/v1/products |
product-service |
Create a new product. | SELLER |
PATCH |
/api/v1/products/{id} |
product-service |
Update a product. | SELLER |
DELETE |
/api/v1/products/{id} |
product-service |
Delete a product. | SELLER |
POST |
/api/v1/products/brands |
product-service |
Create a new brand. | SELLER |
POST |
/api/v1/products/category |
product-service |
Create a new category. | ADMIN |
GET |
/api/v1/search |
search-service |
Search for products with filters. | Public |
GET |
/api/v1/products/{id} |
search-service |
Get detailed information about a product. | Public |
POST |
/api/v1/orders |
order-service |
Create a new order. | CUSTOMER |
GET |
/api/v1/payments/payment-order/{productOrderId} |
payment-service |
Get Razorpay Order ID for payment. | CUSTOMER |
POST |
/api/v1/payments/webhook |
payment-service |
Webhook endpoint for Razorpay. | Public |
auth-service issues an access token and a refresh token. The client must include the access token in the Authorization: Bearer <token> header for all subsequent requests to protected endpoints.@PreAuthorize("hasRole('SELLER')") to restrict access based on user roles (e.g., CUSTOMER, SELLER, ADMIN) embedded within the JWT.JwtAuthenticationFilter that intercepts incoming requests, validates the JWT signature and claims using a shared keystore, and populates the Spring Security context with the authenticated userβs details.Each service is a self-contained module and follows the principles of Hexagonal Architecture for a clean separation of concerns:
model: Contains the core business entities, value objects, and enums.port/driver: Interfaces (ports) that define how the application layer drives the domain (i.e., the use cases).port/driven: Interfaces (ports) that define the contracts for external dependencies like databases or message brokers.service: Implementations of the driver ports. They coordinate calls to domain objects and driven ports to execute business workflows.adapter/inbound: Adapters that drive the application logic, such as REST controllers, gRPC services, and Kafka listeners.adapter/outbound: Adapters that are driven by the application, such as database repository implementations, REST clients, and Kafka producers.Example structure for product-service:
product-service/
βββ src/main/kotlin/com/ethyllium/productservice/
βββ domain/
β βββ model/
β β βββ Product.kt
β βββ port/
β β βββ driver/
β β β βββ ProductService.kt
β β βββ driven/
β β βββ ProductRepository.kt
βββ application/
β βββ service/
β βββ ProductServiceImpl.kt
βββ infrastructure/
βββ adapter/
β βββ inbound/
β β βββ rest/
β β β βββ ProductController.kt
β β βββ grpc/
β β βββ ProductValidationServerService.kt
β βββ outbound/
β βββ persistence/
β β βββ ProductRepositoryImpl.kt
β βββ kafka/
β βββ OutboxEntityRepositoryImpl.kt
βββ ProductServiceApplication.kt